C 言語での i++ 対++i
この記事では、C 言語での接頭辞インクリメントと接尾辞インクリメント演算子、つまり i++
と ++i
の使い分けについて説明します。
C 言語における ++i
と ++i
の主な違い
これら 2つの記法の基本的な部分は、インクリメント単項演算子 ++
であり、これはオペランド(例えば i
)を 1 だけ増加させます。インクリメント演算子は、オペランドの前に接頭辞 ++i
として、またはオペランドの後に接尾辞演算子 -i++
として来ることがあります。
式の中で ++
演算子でインクリメントされた変数の値が使用されている場合には、少し変わった挙動を示すことがあります。この場合、接頭辞インクリメントと接尾辞インクリメントの挙動が異なります。つまり、接頭辞演算子は値が使われる前にオペランドをインクリメントするのに対し、接尾辞演算子は値が使われた後にオペランドをインクリメントします。
その結果、i++
式を引数に用いた printf
関数は、i
の値が 1 インクリメントされる前に i
の値を出力することになります。一方、インクリメント演算子 ++i
を引数に持つ printf
はインクリメントされた値を出力し、以下のサンプルコードで示されているように、最初の繰り返しで 1 になります。
#include <stdio.h>
#include <stdlib.h>
int main() {
int i = 0, j = 0;
while ((i < 5) && (j < 5)) {
/*
postfix increment, i++
the value of i is read and then incremented
*/
printf("i: %d\t", i++);
/*
prefix increment, ++j
the value of j is incremented and then read
*/
printf("j: %d\n", ++j);
}
printf("At the end they have both equal values:\ni: %d\tj: %d\n\n", i, j);
exit(EXIT_SUCCESS);
}
出力:
i: 0 j: 1
i: 1 j: 2
i: 2 j: 3
i: 3 j: 4
i: 4 j: 5
At the end they have both equal values:
i: 5 j: 5
C 言語のループ文で一般的に受け入れられているスタイルとして ++i
記法を使用する
接尾辞演算子と接頭辞演算子は、for
ループ文の中で使用した場合も同じ機能を持ちます。以下のサンプルコードでは、2つの for
の繰り返しが実行されているので、k
の値が同じように表示されます。
なお、for
ループで接尾辞よりも接頭辞インクリメントを使った方がパフォーマンスが向上するという主張はいくつかありますが、ほとんどのアプリケーションでは有効な時間差は無視できるほどのものではありません。一般的に受け入れられているスタイルとして、接頭辞演算子を優先的に使う習慣を身につけることができます。
しかし、もしすでに後置表記を使っているのであれば、対応する最適化フラグを持つ最新のコンパイラを使えば、非効率なループの繰り返しを自動的に排除できると考えてください。
#include <stdio.h>
#include <stdlib.h>
int main() {
for (int k = 0; k < 5; ++k) {
printf("%d ", k);
}
printf("\n");
for (int k = 0; k < 5; k++) {
printf("%d ", k);
}
printf("\n\n");
exit(EXIT_SUCCESS);
}
出力:
0 1 2 3 4
0 1 2 3 4