質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.77%

ポインタを使ったプログラムの書き方。

受付中

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 1,186

score 131

質問したいことがございます。

まず一つめ

仮に&str[i]のアドレスを上げながらメモリに入った数値をそれぞれの値を+1したい場合は

どう書けばよいのでしょうか?
++str[i++] または str[i++]++
for ( ... ;str[i]++, i++) の方が明快か。
と解答を頂いたのですが、
補足になってしまい申し訳ないですが、
例えば、*p は str[i]とも書けるため、ループ三周目のアドレスの指す数値を知りたいときは
if (i == 3){ printf("%d\n", str[3]);};と書けばいいのでしょうか?
仮に*p は str[i]よりよりprintf("%d\n", str[3]);の部分のstr[3]のように書くにはどう書けばいいのでしょうか?if (i == 3){ printf("%d\n", *p ==3);};でしょうか?

二つ目

もう一つ、「仮に&str[i]のアドレスを上げながらメモリに入った数値をそれぞれの値を+1したい場合は
どう書けばよいのでしょうか?
++str[i++] または str[i++]++
for ( ... ;str[i]++, i++) の方が明快か。と言われたのですが、
アドレスとアドレスの指すメモリの数値を上げるならば、++str[i++] または str[i++]++に&を付けてアドレスとアドレスの指すメモリに入る数値を同時にあげる書き方はないのでしょうか?
要は++&str[i++] または &str[i++]++という書き方はないのでしょうか?
ポインタが指すメモリに入った変数の数値と同時に数値を上げるならば
アドレスを上げるのに&の演算子は必要なはずです。
ただ、アドレスを上げながらアドレスの指すメモリに入った数値を上げる書き方が
++str[i++] または str[i++]++と決まっているならば従うしかないですが。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • episteme

    2021/02/15 13:54

    > 意地悪な人だ。

    「"charは配列" って誰が言いました?」ではなく
    「”charは配列" ではありません」って書けばよかった?

    キャンセル

  • carnage0216

    2021/02/15 15:09

    そろそろ答えを教えてください。

    キャンセル

  • maisumakun

    2021/02/15 15:11

    > そろそろ答えを教えてください。

    すでに多数回答がついている状況で、ことさらに求めるものがあるのであれば、わからない点を強調していただければと思います。

    キャンセル

回答 4

+3

例えばこんな配列があるとしよう.
3つの要素 str[0],str[1],str[2] の値をそれぞれ+1すれば,かわいい動物の名称を示す文字列にすることができる.

char str[4] = { 'C'-1, 'a'-1, 't'-1 };

そのような処理が行いたいという話なのであれば,最もシンプルな方法はこうだ.

++str[0];
++str[1];
++str[2];

やりたいことを素直に実装した.完遂したと言える.

「同じような記述を3回も繰り返すすの嫌だから,俺はループで書くぜ!」とか言うならば,こうだろう.

for( int i=0; i<3; ++i )
{   ++str[i];   }

これで十分ではなかろうか.
これ以上,何を望むのか?

わざわざポインタ型の変数pを持ち出して,以下のようにいろんな形に書くこともできるだろうが,そこには特に面白いこともないように思える.

char *p = str;
for( int i=0; i<3; ++i )
{   ++( *(p+i) );   }
char *p = str;
for( int i=0; i<3; ++i )
{   ++p[i]; }
for( char *p=str; *p; ++p )
{   ++(*p); }

結論:難読コードを目指すとかいう話でないならば,素直に書けばどうか.
自分自身で把握し難くなるような文法を持ち出しても無意味な苦労が増えるばかりであろう.


[追記]
以下の2パターンが混じって混乱しているようにも見える.

(1)ポインタpが,常に「いじくるべき要素のアドレス」を指すように pを更新しながら配列要素をいじくる

//配列の先頭要素のアドレスを指すポインタpがあって…
char *p = &(str[0]);  //単に p = str; でも同じ

//先頭要素の値を100に変更
*p = 100;

//2番目の要素の値を200に変更する
++p;  //pのアドレスを「2番目の要素のアドレス」に更新して…
*p = 200;  //2番目の要素の値を変更

//3番目の要素の値を300に変更する
++p;  //pのアドレスを「3番目の要素のアドレス」に更新して…
*p = 300;  //3番目の要素の値を変更

(2)ポインタpは「配列の先頭要素のアドレス」を指すもので,いじくる要素のアドレスを「pの値からのアドレスオフセット」で示す

//配列の先頭要素のアドレスを指すポインタpがあって…
char *p = &(str[0]);  //単に p = str; でも同じ

//先頭要素の値を100に変更
*p = 100;

//2番目の要素の値を200に変更する
*(p + 1) = 200;  //2番目の要素の値を変更

//3番目の要素の値を300に変更する
*(p + 2) = 300;  //3番目の要素の値を変更

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/02/17 13:33

    I bet you're right.

    キャンセル

  • 2021/02/17 13:42

    (他人に対して「言葉を正しく使え」とか言ってるくせに,正しい英語を書けている気がしないという…
    "in Japanese" じゃなくて "with Japanese" とすべきだろうか?とか,いろいろと判断がつかぬ…)

    キャンセル

  • 2021/02/17 13:51

    never mind. I believe such difference seems to be itsy-bitsy.

    キャンセル

+2

str[i]++;
i++;

ではダメなんでしょうか。
ダメな理由はなんでしょうか

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/02/15 11:22

    ありがとうございます。そうではなく、変数iの数値の上げ方の書き方はわかるのです。

    二つ目の疑問については、なぜポインタのアドレス&str[i]とポインタの指すアドレスの中身のメモリに入っている変数iの数値を繰り上げるのに、
    ++str[i++] または str[i++]++と&が付かず、
    要は++&str[i++] または &str[i++]++という書き方ではないのか全く分からないのです。
    なぜなら、str[i++] だけではポインタの指すアドレスの中身のメモリに入っている変数iの数値しか変わらないのでは?と思ったためです。

    キャンセル

  • 2021/02/16 15:42 編集

    ++str[i]; i++;だとしても++str[i];の++は必要ですか?
    i++でstr[0],str[1],str[2]...と(配列の)アドレスが上がっていくのでstr[i]; i++;だめでいいのでは?と思っています。

    キャンセル

+2

&str[i]のアドレスを上げながらメモリに入った数値をそれぞれの値を+1したい場合は

悩むぐらいであれば、アドレスと中身の数値を別々にインクリメントすべきです。

「コードゴルフで1文字でも書くのが惜しい」など特殊な状況にないのであれば、インクリメントを式の途中に組み込むのは、可読性を下げるだけとなります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/02/15 15:53

    > また、が+1されるとstr[i]のポインタのアドレス自体ではなく、
    アドレスに入っているメモリの値が+1され、のは5つのうちどれですか?

    (未定義な動作に突っ込んだ場合を無視するなら)どれでも起きません。アクセスしただけでメモリの中身が変化するkとおはありません。

    キャンセル

  • 2021/02/16 01:18

    >>悩むぐらいであれば、アドレスと中身の数値を別々にインクリメントすべきです。
    に関して、どのように別々にインクリメントすればよいのでしょうか?

    キャンセル

  • 2021/02/16 02:28

    いや、だから str[i]++ と i++ だってば。

    キャンセル

+1

str[i]が指し示す位置を動かしつつ、str[i]の中身を変えたいということであれば
以下のように書けばいいだけなんだけど。
↓の例では配列の中身を全て0で初期化しているので出力結果は全て1になります。

#include <stdio.h>
int main(void){
    int i;
    int str[5]={0};

    for (i = 0; i < 5; i++){
        str[i]++;
        printf("%d\n", str[i]);
    }
}

そもそも配列の指し示す位置を動かす為に&を付ける必要があるという思い込みが
間違っていて、単純にstr[0]、str[1]、str[2]としていけば指し示す位置を
変更出来るということが理解出来ていないのかな?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/02/16 15:36

    その部分、そのまま引用してもらえますか?
    http://www.9cguide.appspot.com/15-03.html
    これ↑のどこかですよね?

    キャンセル

  • 2021/02/17 09:11

    「& は何に付けるのか、付けるとどうなるのか」を説明してください。

    キャンセル

  • 2021/02/17 09:13 編集

    「* は何に付けるのか、付けるとどうなるのか」を説明してください。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る