C言語関係掲示板

過去ログ

No.81.Short型について


#include<stdio.h>
int main(void)
{
short b ;
short c ;
int a ;

printf("数値を入力 ");
scanf("%d",&b);

printf("数値を入力 ");
scanf("%d",&c);

a = c * b ;

printf("答え %d\n", a);

return 0;
}

単純な掛け算の計算ですが、上記のソースを実行すると計算結果が
0になってしまいます。(例:100*100=0)
そこで色々試してみると、上記赤字(変数の宣言)又は、青字のソ
ースのどちらかを、上下逆の順番にすると計算できます。
参考書など調べたが、なぜそうなるのか解りません。
どなたか助言を下さい、よろしくお願いします。

コンパイラ:Borland C++Compiler5.5 OS:Win2000Pro


> scanf("%d",&b);

修飾子を%d→%hdとすれば直ると思います。
そのコンパイラはshortが2byte、intが4byteなので今のコードだと2byte分関係ないとこを潰してるんじゃないでしょうか。
なので先に入力した100が消えちゃってるのではないかと。
LSI-Cだとintも2byteなんで%dでもいけるんですけどね。

VCでも試すとこちらはちゃんと10000てでますね。
スタックからの変数の確保の仕方の違いでしょうか?
詳しい方教えてくださいませ。


ども。

えーほんとー?!とおもって試してみたらほんとでした。。
修行がたりませんね。。。


>そのコンパイラはshortが2byte、intが4byteなので今のコードだと2byte分関係ないとこを潰してるんじゃないでしょうか。
>なので先に入力した100が消えちゃってるのではないかと。

ランタイムライブラリリファレンスをみたら%dはintのポインタを想定している
とのことなので、この解釈であっているようです。

念のため、printf("%d %d",&b,&c)で、マッピングを調べたところ、その差は
2(バイト)で、パディングはありませんでした。アドレスはcの方が先でした
(多分、BCCなら再現性あり)。
さらに、検証しやすいようにプログラム中の%dをすべて%xに変えた上で、
100(任意)、230200としたところ、見事に4600(=2300*0002)となりました。
別に230200でなくても同様の結果が得られるはずです。エンディアンに注意して
考えてみてください(注 この文の数値は16進数)。

あ、単純に2バイトで入らない数値をcにいれて、そのあとで、bとcを表示させた
方がわかりやすいかも。さらに、BCBとかでソースレベルデバッガが使えるなら
そっちの方が手軽ですね。


>VCでも試すとこちらはちゃんと10000てでますね。
>スタックからの変数の確保の仕方の違いでしょうか?
>詳しい方教えてくださいませ。

ちょっと確実なことは言えませんが、おそらく%dとかの仕様の違いかと。
今、手元にVC(のリファレンス)がないので、ちょっと確認できません。
# のってるかな。。

でも、どうやってるんでしょね?意外と、shortでも配列じゃなければ
4とか8バイトでアラインメントとってたりして。そうすればshortか
intか関係なく%dで済むし(「%dとかの仕様の違い」説は違うことになります)。


ところで、この問題ってUNIXでやったらバスエラーがでるのかなーと
おもいましたが、コンパイラ固有の問題なので確認できませんね。。


では。


> 意外と、shortでも配列じゃなければ4とか8バイトでアラインメントとってたりして。

私もこれじゃないかなって思います。
試してみたいんですが、日中はVCがない…。

> そうすればshortかintか関係なく%dで済むし

今までリトルエンディアンの利点がいまいちよくわからなくて嫌いだったんですが、、、
なるほど、便利ですね。
バイト数の違う型へのキャストとかも速そう。

戻る


「初心者のためのポイント学習C言語」 Last modified:2002.01.11
Copyright(c) 2000-2002 TOMOJI All Rights Reserved