質問するログイン新規登録

回答編集履歴

1

追記

2020/04/26 11:49

投稿

thkana
thkana

スコア7739

answer CHANGED
@@ -45,4 +45,54 @@
45
45
 
46
46
  ---
47
47
 
48
- ところで、質問のプログラムは(scanf版でも)"12+34-56=[Enter]"と連続して入力してもちゃんと動作する、というのはわかってましたか? (一応の理屈はこの回答中に書かれてますけど)
48
+ ところで、質問のプログラムは(scanf版でも)"12+34-56=[Enter]"と連続して入力してもちゃんと動作する、というのはわかってましたか? (一応の理屈はこの回答中に書かれてますけど)
49
+
50
+ 追記
51
+ ---
52
+ scanf版で"1[Enter]+[Enter]2[Enter]=[Enter]"と入力したときの動作を、コンピュータになったつもりでトレースしてみましょう。
53
+ 説明のため、一応プログラムに行番号をつけておきます。
54
+ ```C++
55
+ 1: scanf("%d", &sum);
56
+ 2: while(true){
57
+ 3: scanf("%c", &cp);
58
+ 4: if(cp == '=') break;
59
+ 5: scanf("%d", &a);
60
+ 6: switch (cp) {
61
+ 7: case '+':
62
+ 8: sum += a;
63
+ 9: break;
64
+ 10: case '-':
65
+ 11: sum -= a;
66
+ 12: break;
67
+ 13: case '*':
68
+ 14: sum *= a;
69
+ 15: break;
70
+ 16: case '/':
71
+ 17: sum /= a;
72
+ 18: break;
73
+ 19: }
74
+ 20: }
75
+ 21: printf("%d\n", sum);
76
+ ```
77
+ これに、"1[Enter]+[Enter]2[Enter]=[Enter]"を喰わせます。
78
+ 1:最初は標準入力は空なので入力待ち。"1[Enter]"を入力するのでsumに1を取り込みます。標準入力には\nが残っています。
79
+ 2:のwhile(true)は素通しで
80
+ 3:これまでの話で、cpには'\n'が入ります。標準入力は空になって
81
+ 4:ifの条件は偽で次へ
82
+ 5:ここでscanfは入力バッファが空なので入力待ちになります。ここに入ってくるデータは"+[Enter]"。"%d"は整数を要求します。'+'はもしかしたら整数の一部かもしれないので取り込みますが、次が'[Enter]'だと整数として解釈出来ないので、scanfは失敗。aの値は変更されないまま、また標準入力には"[Enter]"が入ってまま次に進みます。
83
+ 6:cpには'\n'が入ってますから、どのcaseラベルともマッチしません。
84
+ 20:switch文を抜けて、whileの終わりに到達。2:のwhileのところまで戻りましょう。
85
+ 3:標準入力の先頭は'[Enter]'ですから、cpに'\n'を取り込みます。
86
+ 4:cpは'\n'なので偽
87
+ 5:標準入力が空で入力待ち、"2[Enter]が入力されますので、aには2が入って標準入力には[Enter]が残ります。
88
+ 6:cpは'\n'なのでcaseにマッチなし
89
+ 20:while終わり、2:に戻って
90
+ 3:標準入力は'[Enter]'で'\n'をcpに取り込み
91
+ 4:ifの条件は偽で次へ
92
+ 5:標準入力は空なので入力待ち。"=[Enter]"が入力されますが、数値には変換不可で標準入力には"=[Enter]"が入った状態で次に
93
+ 6:cpは'\n'なのでマッチなし
94
+ 20:while終わり、2:に戻って
95
+ 3:標準入力の先頭は'='なので、cpに取り込みます。標準入力には"[Enter]"が残っています(もう関係ないけど)
96
+ 4:cpが'='なのでif文の判定式が真でbreak; 21:へ
97
+ 21:さて、sumは...最初に設定された1から変更なし。なので1を表示します。
98
+ 以上、終わり。