C言語を学び始めると(私は独学ですが)最初に出てくるのが,キーボードからの入力にscanf関数を使うことです。この関数は,暴走させたり,思い通りの入力にならなかったりする使いにくい関数です。入力値を代入する場所(下のプログラムでは&iとsです。入門本では「&はおまじないと考えよ」などと書かれています。sには&が付いていません。きちんと説明しないといけないですね)の指定を間違えると,パソコン中のとんでもない場所のメモリを書き替えてしまって,パソコンがハングアップする場合があります。後者の例を示します。
上のプログラムは,まず,キーボードから整数の入力を要求します(6行目)。入力された値を書き出した後,再びキーボードから文字列の入力を要求します(9行目)。そして,その値を書き出した後,5秒間待って(12行目)終了します。
下の実行結果は,整数の入力要求に123と答え,文字列の入力要求にabcと答えた結果です。意図した通り,i=123とs=「abc」がうまく取り入れられていることが分かります。
ところが,整数の入力要求にaと答える(正しい応答ではありませんが)と,上とは異なり,2回目の入力を待たずに,下の様に5秒止めるところに行ってしまいました。不可解です。
上の実行結果にこの不可解な挙動の理由のヒントが現れています。iに入力するべき所に,「a」と答えているにもかかわらず,iには「a」が入らず(整数型変数ですから入るわけはありませんが),999になっています。これは,プログラムの最初に初期値として与えた値です。そして,キーボードから入れた「a」は2回目の応答として扱われました。これらのことから分かることは次のようになります。
整数iを受け取るscanf文に文字を答えると,キーボードからの値は門前払いして,iの値は変えられない。次に文字列sを受け取るscanf文が実行されたとき,門前払いされた文字(列)が,ここで受け取られる。scanfは入力値を“門前払い”することがあることにより,不可解な挙動になるということでした。