6

他の人のプログラムをデバッグしているときに、興味深い結果を生成するコードに出くわしました。

この動作を説明するために、小さなプログラムを作成しました。

#include <stdio.h>

int main()
{
        char* word = "foobar"; int i, iterator = 0;
        for (i = 0; i < 6; i++ && iterator++)
          printf("%c", word[iterator]);
        return 0;
}

これが文字列を出力する正しい方法ではないことはわかっています。これはデモンストレーションのみを目的としています。

ここでは、出力が明らかに「foobar」であると予想していましたが、代わりに「ffooba」です。基本的に、最初の文字を 2 回読み取ります。最初にiterator++実行された場合は何も起こりません。

なぜこれが起こるのか誰か説明できますか?

4

4 に答える 4

11

iterator++実際には、初めて実行されるわけではありません。この++演算子は、変数の現在の値を返し、それをインクリメントします。したがって、初回i++は と等しくなり0ます。&&短絡するためiterator++、初回は実行されません。

これを修正するには、 short-circuiting ではなく、無条件に両方を評価するコンマ演算子を使用できます&&

于 2012-09-29T07:00:08.693 に答える
5

の結果は、最初の反復でゼロになるi++現在の値です。iこれは iterator++、ショート サーキュティングのため、最初の反復では実行されないことを意味します ( の右側&&は、左側が "true" の場合にのみ実行されます)。

修正するには、コンマ演算子を使用できます (既に提案されているように、または)インクリメント++iの後に値を返す使用i(ただし、両方を常に評価する必要があることはコンマ演算子の方が明らかです)。

于 2012-09-29T06:59:46.150 に答える
3

gdbたとえば、デバッガーの使用方法と、警告とデバッグ情報を使用してコンパイルする方法を実際に学ぶ必要がありますgcc -Wall -g(Linux システムを想定)。最近のgccwithは、計算された値が操作の前に使用されていない-Wallという警告を出します。&&

ループのインクリメント部分forが奇妙です。それはそうです(しかし、代わりにi++ && iterator++そうあるべきです)。i++, iterator++

が 0 の場合i(最初の反復で)、i++結果として 0 が返されるため、偽であるため、iterator++は実行されません。

于 2012-09-29T07:01:13.297 に答える
2

私は論理演算子についての K&R を読んでいます。あなたの質問を説明できる本の語源を引用させてください。「&& または || で接続された式は左から右に評価され、結果の真偽が判明するとすぐに評価が停止します。」これらをよく理解すれば、出力は困惑しません。

于 2012-09-29T12:29:54.187 に答える