読者です 読者をやめる 読者になる 読者になる

ベスパライフ

日記・備忘録。ベスパもってないです。

間接演算子のインクリメント

C言語

以下の様な処理で、予期しない動作をしてかなり悩んだ

func(char* hoge){
*hoge ++;
}

実際にはもっと処理は長いのだが、どこが原因かを突き止めること自体に悩んだ。

上記の意図としては、hogeのアドレスが指し示す値をインクリメントして欲しくて記述したものだった。つまり次のような意図で記述した

(*hoge) ++;

しかしそうはならず、次のように動作した

*(hoge ++);

演算子の結合性の優先度云々の話なのだが、まさかここでつまずくとは思わなかった。
たしか優先度はコンパイラにも言語にも依存するので曖昧な記述をした自分が悪いのだが、あまりにも直感に反した動作をされてショックを受けた。

また似たような話で、ポインタ変数を宣言するときに

char* hoge;

とするのは、結合性の観点から見るとやめておいたほうがよい。推奨は次のような記述である。

char *hoge;

char* hogeのほうが「charのポインタ変数なんだな」感がでて良いと思うかもしれないが(というか自分はそう思うのだが)、次のような書き方をしたときには注意が必要である。

char* hoge, piyo;

これはchar型のポインタ変数hogeと、char型の変数piyoが宣言されている。
見た目による直感的な動作とは異なるし、全てをポインタ変数にするならば全てに*をつけなければならないので、char *hogeと書いたほうが良い。
曖昧な記述は避けるべきという考え方からすると、見た目による直感に反した動作をする書き方は避けるべきだろう。

間接演算子*を使用するときは、カッコ付きで記述するようにしたほうがわかりやすい。だって

*hoge += 10;

上記が どのような動作をするか、自信をもって答えられないんだもん(だもん)。