『Cプログラミング専門課程』目次第4章メモリ

4.1 アドレス (3)


次のプログラムは非常に簡単なプログラムです。1から100までの2乗の和 を求めています。

サンプルプログラム

   1: /*  sum2.c  --  2乗和  */
   2: 
   3: #include        <stdio.h>
   4: 
   5: main()
   6: {
   7:         int     i;
   8:         int     sum = 0;
   9: 
  10:         for( i=1 ; i<=100; ++i )
  11:                 sum += i*i;
  12: 
  13:         printf( "sum = %d\n", sum ); 
  14: }

このプログラムを2つのコンピュータで実行すると、次のように結果が異な りました。


	コンピュータ(A)	sum = 338350		

	コンピュータ(B)	sum = 10670

最後に足される数は100*100で10000です。だから、当然総和sumは10000より もはるかに大きな数値になるはずで、(B)のコンピュータの結果は間違いです。 しかし、2つのコンピュータで動かしたプログラムは、全く同じCのソースプ ログラムをコンパイルしたものです。では、なぜ(B)では間違いが起きたので しょうか。

総和sumはint型です。int型はコンピュータ、コンパイラ、あるいはオプショ ン指定により2バイトになったり4バイトになったりします。これにより、あ つかえる値の範囲がはるかに変化します。2バイトint 型では、-32768〜 +32767とかなり狭い範囲しか扱えないので、注意しないとすぐにオーバーフロー します。問題は、オーバーフローした時、普通は一切エラーにならず、オーバー した部分は無視し、下位の2バイト分が演算結果とされてしまうので、思わぬ 結果になります。正数と正数を足すと負数になることもあります。数値が2バ イトで収まらない場合には、 int型ではなく、4バイトの精度があるlong型を 使うべきです。たとえ自分が今使っているコンピュータが4バイトint型であっ てもです。

このトラブルが問題になるのは、プログラムの移植のときです。int型が4 バイトのコンピュータから、2バイトのコンピュータに下方に移植するときに は極めて注意が必要です。だから、色々な種類のコンピュータで動かすつもり のプログラムの場合、整数だからといって気軽にint型を使うのはトラブルの 元になります。少なくとも、2バイトで表現できない可能性が少しでもある場 合には、絶対にint型にしてはいけません。このように基本型でありながらコ ンピュータにより実装が異なるものは要注意です。より多くのコンピュータで 動作させたいのなら、プログラムから全てのint型を取り除くくらいの意気込 みが必要です。

なお、本書ではint型をよく使用しています。long型にしないとトラブルの 可能性がある場合を除いて、より一般的に使用されているint型を使うように しています。

*常識*
  • int型は移植で問題を起こしやすい。

⇒⇒⇒⇒4.2 バイトオーダーへ


Copyright1996 Hirofumi Fujiwara. No reproduction or republication without written permission
『Cプログラミング専門課程』目次第4章メモリ