- ベストアンサー
ループ動作についての疑問
- プログラムを実行した結果、空白文字が文字列として読み込まれず、変数「moji」には「ABC\0」という値が入ります。
- 実際の動作では、scanf関数が実行された後、forループが入力した単語数分繰り返され、putchar関数で改行を出力します。
- 一つしかない変数「moji」を利用して、入力した単語を一文字ずつ出力しています。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
あ、あとscanfの動作についても一応説明しておきます。 入力された文字列はバッファという場所に一端置かれます。 scanfは実はこのバッファから文字列を読みとっています。 >入力:ABC 123 XYZ 567 この場合まずABCだけ読み込まれ、それ以外の文字列はバッファに置かれたまま残ります。 ループで戻ってきて2回目のscanfでは、バッファに残った123が読み込まれるため入力待ちはありません。 ちなみにバッファをクリアする関数として、fflushがあります。 putchar('\n');の後にfflush(stdin);と追加して実行してみて下さい。 scanfの動作がなんとなく掴めると思います。
その他の回答 (7)
- asuncion
- ベストアンサー率33% (2127/6289)
fflush(stdin)は、確か未定義のはずです。 そういうコードを書いてはいけないと思います。
お礼
ご回答ありがとうございます。 fflush(stdin)については調べてみたいと思います。
- sankaku197
- ベストアンサー率47% (29/61)
度々すみません、どうでもいい事なんですがNo.4は微妙に嘘ですね。 forの後にまたすぐforが来たら表示結果は「ABCABCABC」となります。 putchar('\n');だけが実行されずループを繰り返すなら「ABC123XYZ567」です。 折角なんで、もう一つ。 この質問ではmojiを一つの変数と言っていますが、正確にはmoji[0]~[9]の10個の変数なんですよね。 moji[0] A moji[1] B moji[2] C moji[3] \0 だからfor(i=0; moji[i]; i++)ではこうなるわけです。 ループ1回目 moji[0] == A ループ2回目 moji[1] == B ループ3回目 moji[2] == C ループ4回目 moji[3] == \0 == 0 == ループ終了
お礼
ご丁寧な回答、ありがとうございます。 とても参考になりました。
- koi1234
- ベストアンサー率53% (1866/3459)
>1つしかない変数の動作は分かりました。 >では、for文内の出力動作はどうなっているのでしょうか? >for文は条件式の成立後にまたfor文が実行されているように見えます。 1つしかない変数が都度変化した後に再度for分が繰り返されているだけです 1つしかない変数の動作を理解してれば悩むことないと思いますが #2さんが書かれてる1回目2回目ってのはwhile文に対しての回数です
お礼
こちらの勘違いでputchar('\n');は確かに実行されていました。 for内を抜けた後の動作も「ANo.5」のご回答で解決しました。 どうもありがとうございました。
- sankaku197
- ベストアンサー率47% (29/61)
まさかとは思いますが、\0は改行じゃないですよ? あくまでPCが文字列の終端と認識するための記号です。 もしputchar('\n');が実行されず、forforfor・・・と実行されるとしたら 出力結果は「ABC123XYZ567」と表示されます。
お礼
ご回答ありがとうございます。 putchar('\n');は確かに実行されていました。 こちらの勘違いです。申し訳ありません。
- kmee
- ベストアンサー率55% (1857/3366)
for(A ; B; C ) とあった場合 1)ループ開始前に A を評価(実行)する 2) Bを評価する。偽(値が0)ならループを抜ける 3)ループ本体の実行 4) Cを評価(実行する) 5) 2)へ戻る となります。条件が成立つ間はループ本体、B,Cを繰り返します。forはここまでのループで1セットです。 > scanf、for文、for文、for文、for文、putchar('\n')と処理しているように見えます とありますが、whileで繰り返されているのはあくまで > scanf、for文、putchar('\n') であって、for文として moji[i]が真( != 0 ) の間、putchar(moji[i]); i++ が繰り返されている、というものです。
お礼
ご丁寧な解説ありがとうございます。 初心者に対するお心遣い、大変助かります。
補足
ご丁寧な回答ありがとうございます。 scanfやwhile、forの動作は全てではありませんが存じております。 for内で理解できていないのが、forから抜けた後との動作になります。 1回目のfor内で条件式が成立すると、「ABC」と出力するかと思います。 forを抜けますと、while内のputchar('\n');が処理され改行が出力されると思ったのですが、今度は「123」と出力しています。 これは、再度for文に戻ったと見えてしまうのですが、実際はどのような動作をしているかをアドバイス頂けたら助かります。 また、scanfの処理ですが、入力する際「ABC 123 XYZ 567」と空白で区切りながら入れています。 このデータはバッファに記録されていると思うのですが、動作的には「ANo.2」で回答頂いた内容かと思いますので、何となくイメージは出来たのですが、根本的な動作原理が良く分かりません。 この辺りの解説も添えていただけたら幸いです。 お願いできますでしょうか?
- asuncion
- ベストアンサー率33% (2127/6289)
1回目のscanf():配列moji[] に、'A', 'B', 'C', '\0' が入ります。 2回目のscanf():配列moji[] に、'1', '2', '3', '\0' が入ります。前回のscanf()で読んだ内容を上書きします。 3回目のscanf():配列moji[] に、'X', 'Y', 'Z', '\0' が入ります。前回のscanf()で読んだ内容を上書きします。 4回目のscanf():配列moji[] に、'5', '6', '7', '\0' が入ります。前回のscanf()で読んだ内容を上書きします。 これで、1つしかない変数mojiをどう使っているか、おわかりですね。
お礼
ご回答ありがとうございます。
補足
1つしかない変数の動作は分かりました。 では、for文内の出力動作はどうなっているのでしょうか? for文は条件式の成立後にまたfor文が実行されているように見えます。 while以下scanf、for文、putchar('\n')と順番に処理していくのではと思ったのですが、実際実行してみると、scanf、for文、for文、for文、for文、putchar('\n')と処理しているように見えます。 この動作について教えていただけませんでしょうか? よろしくお願いいたします。
- kmee
- ベストアンサー率55% (1857/3366)
> 実際の動作ではscanf関数が実行された後、for関数が初めに入力した空白で区切られた単語数分 まず、forは構文であって関数ではありません。 まず、whileもループを作るのはおわかりですか? まず、whileのループの中身だけを解析して、何をやっているか理解しましょう。その中身を繰り返しています。 単語の数だけ繰り返されるのは、forだけではありません。 ....にしても、ちょっとトリッキーなコードだなぁ
お礼
ご回答ありがとうございます。
お礼
scanfの動作について理解できました。 これが入力したデータを何度も出力していたことが分かりました。 ありがとうございました。 「ANo.8」のご回答もありましたので、fflush(stdin)については調べてみます。