先日の答え

 先日C言語に関する問題を出したのですが、その解答編。


#include
 
(中略)
  int a=10000;
scanf("%d",a);
return 0;
}

 
 まあ、どこが間違えているかってのは一目瞭然で、aが本当は&aでなければいけないのですが、これを実行するとどうなるかというのが問題です。
 
 正解はメモリアドレスの10000番地が書き換わってプログラムが作者の意図しない動作をする、です。ただし、これはシンプルに考えた場合の話で、インテリジェントなOS上で動作をさせるときは、何らかの保護機構が働きます。(そんなに単純にメモリの内容を書き換えられたらWindowsもたまったもんじゃないでしょう。)
 
 scanfで渡すaは実数ではなくアドレスで渡さなければいけません。しかし、問題のようにaを実数で渡してしまった場合、aの中に入っている10000がアドレス型に暗黙キャストされます。問題の前提としてデータサイズは全て32bitと仮定して良いとしてあるため、32bitコンパイラで生成されるint型もメモリアドレスのサイズも32bitになるため、10000番地がscanfで入力した値に書き換えられます。
 
 実はこういう間違いは昔のプログラムに多く、昔はコンパイラがそれほど賢くなかったので、プログラマがポインタの代わりに実数型にアドレスを突っ込んでいるような間違いも存在しているらしいのです。


 int a,b;
 a=&b;

 
 冗談抜きでこういうプログラムを書いているものもあります。この場合int型がメモリアドレスのサイズと同じサイズを持っていれば正しく動作しますが、int型が16bit、メモリアドレスが32bitというようなアーキテクチャで動作させる場合は、当然int型にメモリアドレスが入りきらず不正な動作をすることになります。
 
 さて、話は変わって今日の問題。例によってTAがあったため、学生のプログラムを見回っていたら珍解答が沢山あって面白かったです。その中の1つ。

#include

int main(void);
int main(void){
int a,i;
a=0;
for(i=0;i<10;i++){
a=+2;
}
printf("%d",a);
return 0;
}


 
 このとき出力される数字はいくらでしょう?
 暇なら答えてください。トラックバック待ってます。