インクリメントで実験
C言語のインクリメントについて、知らない部分があったので残しておく。
以下のコードをコンパイルして実行する
#include <stdio.h>
int sum(int a, int b) {
return a + b;
}
int main() {
int a = 1;
int b = 2;
printf("sum: %d\n", sum(a++, b));
printf("a: %d\n", a);
}
すると、出力は以下のようになる。
sum: 3
a: 2
表面上は、引数として、int型を渡す際に、インクリメントして渡すと、関数の処理が終わったあとに、インクリメントされているように見える。
次に、以下のコードをコンパイルして実行する。
#include <stdio.h>
int sum(int a, int b) {
return a + b;
}
int main() {
int a = 1;
int b = 2;
printf("sum: %d\n", sum(++a, b));
printf("a: %d\n", a);
}
実行結果は、以下のようになる。
sum: 4
a: 2
これも、表面上は++a
のようにすることで、インクリメントが行われてから、引数として渡されているように見える。
前置インクリメントと、後置インクリメント
前項の実験の結果は以下のような仕様によってもたらされる。
int a = 1;
int b = a++; // a+1 (すなわち 2) を a に格納し、
// 以前の a の値 (すなわち 1) を返します。
// この行の後、 b == 1、 a == 2 になります。
a = 1;
int c = ++a; // a+1 (すなわち 2) を a に格納し、
// 新しい a の値 (すなわち 2) を返します。
// この行の後、 c == 2、 a == 2 になります。
cppreferenceより引用
つまり、直感的に想像していた処理とは異なり、関数の呼び出し前後の順序が問題となっているわけではない。
++x
といった書き方を前置インクリメントと呼び、x++
といった書き方を後置インクリメントと呼ぶ。
恥ずかしながら、両者の違いをあまり意識しておらず、バグを生んでいたため、備忘録として残しておく。
参考文献
インクリメント/デクリメント演算子, cppreference.com, https://ja.cppreference.com/w/c/language/operator_incdec