【11月勉強会】汎整数拡張とか
北本です。2回目の投稿になります。
ブログに書くのが遅くなりましたが、18日(土)に弊社で勉強会を実施しました。参加者は、高木、佐藤、北本の3人。今回テーマとしたのはCとC++。両言語の歴史(規格の変遷)や型変換あたりを扱いました。
型変換に関しては、
・汎整数拡張
・通常の算術型変換
・既定の実引数拡張
といったあたりがキーワードでしょうか。
今回の勉強会はパソコンを使わず机上でやっていたので、家に帰って実際に確認してみようと例えば以下のようなコードを書いてみました。
何気に自分の書いたコードを初めて全世界(?)に晒すことになるので少し緊張。大したものではないですが。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <stdio.h> int main(void) { unsigned short us1 = 0xffff; unsigned short us2 = 0x0001; unsigned short us3 = us1 + us2; printf("%hu\n", us3); if (us3 > 0xffff) { puts("us3 > 0xffff"); } else { puts("us3 <= 0xffff"); } if (us1 + us2 > 0xffff) { puts("us1 + us2 > 0xffff"); } else { puts("us1 + us2 <= 0xffff"); } return 0; } |
出力結果は以下のようになりました。(short型が2バイトの環境)
us3 <= 0xffff
us1 + us2 > 0xffff
us3はus1 + us2を代入したものですから、us3とus1 + us2は同じ値になりそうですが、2つのif文の結果を見たところ違う値とみなされているようです。
us1 + us2の加算が、汎整数拡張によって各オペランドがunsigned short型からint型に拡張されて行われ、int型の0x10000という計算結果になり、それをunsigned short型のus3へ代入すると切り詰められて0x0000になりますが、下の方のif文ではint型の0x10000のまま比較が行われているため、このような結果になるわけですね。
単純に、
printf(“%d\n”, us3);
printf(“%d\n”, us1 + us2);
としてもそれぞれ0x0000、0x10000であることが確かめられますが、関数を介すると既定の実引数拡張の話も少し絡んできてしまうので、このような感じにしてみました。
型の問題は、私のような実務経験の浅い者にとっては盲点になりやすいところのような気がします。自分一人で何か好き勝手にプログラムを作ろうとする際、使用する型といえば、int、double、charあたりがほとんどで、shortやfloatを使おうとすることってあまりないんですよね。故に、int・double間以外の型変換に関して意識を払う機会が少なくなりがちかもしれません。
今回の勉強会で、型変換に関しての理解は並の新人とは違うと言えるようになっていられたらいいですね。