事の歴史:
インクリメント演算子 ++ とデクリメント演算子 -- はCの最初のバージョンに登場し、低水準のマシン言語の機能からインスパイアを受けました。プレフィックス形式(++i、--i)とポストフィックス形式(i++、i--)は、プログラマーに異なるセマンティクスを提供し、計算コストは最小限に抑えられます。
問題:
最大の難しさは、プレフィックス形式とポストフィックス形式が異なる動作をすることです。プレフィックス形式はまず値を増減させ、その後結果を返しますが、ポストフィックス形式はまず元の値を返し、その後変数を変更します。ネストされた式では、これはしばしば混乱を引き起こし、予期しない動作や値の誤った使用を招くことがあります。
解決策:
各形式が何を返すのかを明確に区別することが重要です。即座に新しい値が必要な場合にはプレフィックスバージョンを使用します。古い値を保持することが重要な場合(例:関数に渡す場合やカウンタのロジックなど)にはポストフィックスを使用します。複数のインクリメントを含む複雑な式は避け、副作用とともに使用することは混在させないことが良い習慣です。
コード例:
int i = 5; printf("%d\n", ++i); // 6と表示される printf("%d\n", i++); // 6と表示されるが、iは7になる
主な特徴:
i = i++を使用することはできますか?何が起こりますか?
i = i++構文の使用は未定義の動作を引き起こします:コンパイラは期待される結果を保証する義務がなく、プログラムは予測できない動作をする可能性があります。
コード例:
int i = 1; i = i++; printf("%d\n", i); // 結果はコンパイラによって異なる:1または2が表示される可能性がある
同じ変数を複数回使用してインクリメントを1行で使用することは危険ですか?
同じ変数を1つの式の中で複数回変更する場合(例:f(i++, i++))、C標準では動作が未定義です。最終的な結果はコンパイラの具体的な実装に依存します。
i++は常に++iよりも速いですか?
いいえ。現代のコンパイラでは、通常違いはなく、コンパイラは両方の形式を同じように最適化します、戻り値が使用されない限り。
ループで開発者は次のように書きました:
for (int i = 0; i < 10;) arr[i] = i++ * 2;
利点:
欠点:
for (int i = 0; i < 10; i++) arr[i] = i * 2;
利点:
欠点: