0

これは、内部で何が行われるかを理解するための私自身の実験でした。このプログラムはコンパイラにとって何を意味するのでしょうか?

main()
{
  int c;
  printf("%d\n",c);
  printf("%d ", getchar());


  while ((c == getchar()) != EOF){
    putchar(c);
  }
}

c は getchar() (c == getchar()) と等しくなければならないと言った場合、while ループを通らないのでしょうか? 今、私は自分のコード、つまり c が意味するものについて本当に混乱しています!

また、このコードでは:

main()
{
int c;
c = getchar()
while ((c = getchar()) != EOF)
putchar(c);
}

int ctoを変更するとint c = getchar()、次のように簡単に書けないのはなぜですか。

while (c != EOF)(
    putchar(c);
    c = getchar();
    }

コンパイラは、前のステートメントからc = getchar()、なぜステートメントを再度記述しなければならないのかを知る必要があります。混乱していたらごめんなさい。

4

4 に答える 4

4
while ((c==getchar()) != EOF) {
  ...
}

whileループです。ループの反復ごとに条件を評価し、条件が false の場合にのみ終了します。

あなたの場合、条件は次のとおりです。

(c==getchar()) != EOF)

これは無意味な表現ですが、とにかく調べてみましょう。

まず、プログラムは以下を評価します。

    getchar()

これは、標準入力からキーストロークを取得します。式の値はキーの値です。

それで:

 c==getchar()

これは の結果をgetchar()取得し、現在 にあるものと比較しcます。最初のプログラムでcは、 は初期化されていないため、その値は不定です。c定義済みの値がある場合、 または のいずれかc==getchar()に評価されます。定義された値がないため、定義された値もありません。truefalsecc==getchar()

ここで、プログラムは次を評価します。

(c==getchar())

あなたの場合は未定義であることを除いて、どちらもtrueまたはです。false

次に、プログラムは次のことを考慮します。

(c==getchar()) != EOF

つまり、true-false値をEOF;と比較します。これは特に意味がありません。あなたの場合、未初期化の未定義の動作がまだありますc

つまり、c初期化されている場合、式は標準入力からキーを取得し、trueまたはfalseと比較しますEOF。おっしゃる通り、ナンセンスな表現です。

于 2013-09-04T02:43:05.057 に答える
3

ボンネットの下を見たいと言っているのですか?すごい!飛び込みましょう:)

while ((c == getchar()) != EOF)

他の人が指摘したように、これはwhile ((c = getchar()) != EOF). =等価テスト ( ) ではなく代入 ( ) を行う理由==は、実際には 2 行のコードを 1 行にまとめるからです:c = getchar();while(c != EOF). したがって、現在読み取られている文字が であるk場合、プログラムは次のような方法でそれを評価します。

while ((c = getchar()) != EOF)
while ((c = 'k') != EOF)
while (('k') != EOF)
while ('k' != EOF)
while (1) // true

そして、それはあなたが何をしようと計画していても、cまだ内部にあるという便利な副作用を持っています.k

他の問題はここにあります:

int c;
printf("%d\n",c);

printfまだ何も割り当てられていないため、文句を言うでしょうc。「宣言」されていますが、「初期化」されていません。そこにないものを印刷することはできません - もし可能であれば、あなたが望まないものを確実に印刷するでしょう。

于 2013-09-04T02:43:37.247 に答える
2

削除する必要がある余分な等号があります。

while ((c == getchar()) != EOF){

する必要があります

while ((c = getchar()) != EOF){

これが何が起こっているかです。が(c == getchar())実行されると、そもそもc初期化されていないため、ガベージ値があります。そのガベージ値は、入力ストリーム内の次の文字と比較され、それらが同じかどうかが確認されます。比較の結果は、0(異なる場合) または1(同じ場合) になります。後者の可能性は非常に低いですが、理論的には、幸運な (?) チャンスによって、ガベージ値が入力ストリームの次の文字と一致する可能性があります。

次に、 0or1を比較して、一致するかどうかを確認しEOFます。まあ、EOF負の値になるでしょう。それが定義によるものです。明らかに負の値と一致しない01、決して一致しないため、ループは無限になります。

2 番目のコード フラグメントについては、次のようになります。

c = getchar();
while ((c = getchar()) != EOF) {

最初の文字が であるかどうかを確認していません。最初の文字の後EOFの値は、条件の代入によってすぐに置き換えられます。最初以外の文字があると仮定すると、コードは機能します。 cgetchar()whileEOF

3 番目のコード フラグメントについては、次のようになります。

c = getchar();
while (c != EOF) {     // corrected your typo of ( instead of {
    putchar(c);
    c = getchar();
}

c = getchar()ループ内で再度記述しなければならない理由は、入力ストリームの 2 番目以降の文字で のwhile値を更新するためです。それ以外の場合、入力ストリームの最初の文字であるcの現在の値を と常に比較し、最初の文字がたまたま でない限り、これも無限ループになります。 cEOFEOF

あなたが望むものを達成する最も簡潔な方法は次のとおりです。

int c; while ((c = getchar()) != EOF) putchar (c);

... 2 番目のコード フラグメントと同様に、最初のコードを実行してgetchar()に割り当てる余分な行を除いたものcです。

于 2013-09-04T02:29:10.523 に答える
1

c == getchar() != EOF意味

c == getchar() は、cresult returned from getchar()が同じ場合に真です。

c == getchar()は常に EOF と等しくないため (真でも偽でも EOF と等しくないため)、プログラムは c を初期化していないため、ここにランダムに表示された文字を出力する無限ループを実行する必要がありますint c;

于 2013-09-04T02:40:55.837 に答える