これらのコードスニペットの違いは何ですか?

私は次のコードスニペットを実行している:

char* head = str;
char* tail = head;
while ( *tail ) {
    ++tail;
}

私は単純化のためにwhileループを変更し、新しいコードは

char* head = str;
char* tail = head;
while ( *tail++ );

私は上記の2つのコードスニペットが同じように動作すると信じています。しかし、2番目の方法はあります! GDBでは、32文字の文字列の場合、ポインタの末尾が31より大きい33よりも大きいことがわかります。

私は本当に困惑している。

2
式( * tail * tail ++ )のは同じですが、副作用は異なる。
追加された 著者 pmg,

4 答え

2番目のコードでは、* tailが0に評価されるかどうかにかかわらず、ポストインクリメントが発生します。

6
追加された
ありがとう。私は何年もCをプログラミングしてきましたが、しばらくしてこのような亀裂を落としてください。
追加された 著者 my_question,

なぜうんざり?

増分は、第1の場合は条件付きであり、第2の場合は無条件である。

2番目の形式はおそらくあまり有用ではないでしょう(ターミネータに戻るためにはデクリメントする必要があるからです)。ただし、割り当ての最後を過ぎたアドレスを計算することは許可されていますが、OKでなければなりません。

2
追加された

最初のコードは * tail が0でないかどうかをチェックし、0でない場合は tail を増やします。 0の場合、 tail をインクリメントする前にループを停止します。

2番目のコードは tail をインクリメントし、 tail の古い値が 0 を指しているかどうかを確認します。そうでなければ、それは続行されます。そうであれば停止しますが、すでに tail がインクリメントされていることに気付きます。

つまり、基本的に最初の1つは 0 を指す tail を残し、2つ目は tail コード> 0

0
追加された

2つめの場合は、適用したい条件を指定する必要があります。そうしないと、その副作用が発生します。

最後に何かを投げてもいい?

0
追加された