c言語で算術型変換がどのように行われているかの質問です。
例えばintが16bitでlongが32bitの環境であるとします。
そして以下のようなプログラムがあるとします。
unsigned long x = 100;
signed int y = 1;
unsigned int z = 5;
long test = x + (y - z);
1、
このときまずy-zについて算術型変換が起きてyとzがunsigned intとなり、
y-z=65532となる。
そしてx/(y-z)について算術型変換が起き、xと(y-z)がunsigned longとり、
x+(y-z)=65632となるのでしょうか?
2、
もしくはx+(y-z)のすべてに算術型変換を起こしてから計算を行うのでしょうか?
y-zの結果の型をunsigned longとして計算し、y-z=4294967292になるのでしょうか?
文章がうまくまとめられていないのですが、どちらになるのでしょうか?
No.8
- 回答日時:
&huってなんだ・・・
%huですね
この回答への補足
みなさん回答ありがとうございます。
一番上の方の補足にみなさんへのお礼や補足を書きます。
まず、(汎)整数拡張ですが、int以下の整数型をintへ拡張するものだと理解しています。
そのため、今回の分かりにくい例ですが、整数拡張は行われた後のものだとして書いたつもりです。
次に、printf表示ですが、unsigned intの計算で式の結果がマイナスになった場合本来はラップアラウンドが生じているはずだと思います。
しかしprintfでは自動的に値を変えてしまうらしく…
ラップアラウンドが生じてる場合は%uで表示する必要があるとのことです。
No.7
- 回答日時:
printf( )が変数の符号や型を解析して自動で表示するわけではないのでこれで値を確認するのはあまり意味がないです。
プログラマ側が型や符号を意識して使わないとだめでしょう。
unsigned shortは &hu で表示しないと意図しない値が表示されることがあります。
No.6
- 回答日時:
なんか間違った方向に誘導されそうですね。
まず、今回は「汎整数拡張」ではなく、「通常の算術型変換」に関するものです。
「通常の算術型変換」について調べてみてください。
次に,評価結果が符号無しになるにもかかわらず、%dや%ldで変換したのでは、正しい結果が得られないのは当然です。
No.5
- 回答日時:
>例えばintが16bitでlongが32bitの環境であるとします。
「LSI C-86 Ver 3.30c 試食版」をRAMディスクに解凍し、実行してみました。
>文章がうまくまとめられていないのですが、どちらになるのでしょうか?
LSI C-86 では、1にも2にもなりませんでした。
・まず( y - z )について、( 1 - ( 5 ) )で、-4。
・次に、test = 100 + ( -4 ) で、96。
となったようで、「型変換が行われた」ことを確認できませんでした。
また、y と z の型を入れ替えても、同様でした(★、( y - z )で先に現れる y を、unsigned int に)。
これらから、( y - z )全体として(デフォルトの)、signed int となっているのかな?と思います。
というか、今回の例では、「整数拡張」をみるのに相応しくない「値」だったんではないでしょうか。
実行結果
x:100 size:4
y: 1 size:2
z: 5 size:2
( y - z ):-4 0000FFFC size:2
test:96
☆No.2 さんと異なるのは、sizeof( ( y - z ) )だけでした。
#include <stdio.h>
void main()
{
unsigned long x = 100;
unsigned int y = 1; /* ★ */
signed int z = 5; /* ★ */
long test;
test = x + ( y - z );
printf( "x:%ld size:%d\n", x, sizeof( unsigned long ) );
printf( "y: %d size:%d\n", y, sizeof( unsigned int ) );
printf( "z: %d size:%d\n", z, sizeof( signed int ) );
printf( "( y - z ):%d %08X size:%d\n", ( y - z ), ( y - z ), sizeof( ( y - z ) ) );
printf( "test:%ld\n", test );
}
No.2
- 回答日時:
手元の環境で、試してみました。
#include <stdio.h>
typedef unsigned long T_UINT32;
typedef signed long T_SINT32;
typedef unsigned short T_UINT16;
typedef signed short T_SINT16;
void run_test()
{
T_UINT32 x = 100;
T_SINT16 y = 1;
T_UINT16 z = 5;
T_SINT32 test = x + (y - z);
printf("----------\n");
printf("x{%d} sizeof{%d}\n", x, sizeof(x));
printf("y{%d} sizeof{%d}\n", y, sizeof(y));
printf("z{%d} sizeof{%d}\n", z, sizeof(z));
printf("test{%d} sizeof{%d}\n", test, sizeof(test));
printf("----------\n");
printf("(y - z){%d} sizeof{%d}\n", (y - z), sizeof(y - z));
}
int main(int argc, char *argv[])
{
run_test();
return 0;
}
/*
実行結果(gcc (GCC) 3.4.2 (mingw-special)):
----------
x{100} sizeof{4}
y{1} sizeof{2}
z{5} sizeof{2}
test{96} sizeof{4}
----------
(y - z){-4} sizeof{4}
実行結果(Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86):
----------
x{100} sizeof{4}
y{1} sizeof{2}
z{5} sizeof{2}
test{96} sizeof{4}
----------
(y - z){-4} sizeof{4}
*/
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語で複数列のデータを1列の...
-
Enterキーを押されたら次の処理...
-
【C言語】全角文字の配列を、全...
-
構造体メンバの初期化
-
fatal error LNK1120: 外部参照...
-
タイムカードのシステムを作り...
-
プログラミング 難問
-
#defineが使用するメモリ領域に...
-
いつもお世話になっております...
-
マイナスからプラスへ転じた時...
-
信頼区間の1.96や1.65ってどこ...
-
「Aに対するBの割合」と「Aに対...
-
AtCoderABC135の問題Cについて
-
Aの値からBの値を除するとは??
-
C言語での引数の省略方法
-
プログラミング初心者です。 Py...
-
doubleの変数にintとintの割り...
-
「指定されたキャストは有効で...
-
エクセルで可視セルにのみ値貼...
-
C言語で電卓を作成する。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
C言語で複数列のデータを1列の...
-
#defineが使用するメモリ領域に...
-
printf による16進表示について
-
空白を含んだ文字列がうまく格...
-
【C言語】全角文字の配列を、全...
-
reallocでエラー
-
C言語のプログラムで、途中で止...
-
構造体メンバの初期化
-
char型2つを結合し、short型に...
-
C言語でのCSVファイルの読み出...
-
エラーについて質問です。
-
Cでファイルの行数をカウントす...
-
矢印キーを押下してコンソール...
-
終了条件Ctrl+zについて,結果表...
-
受信データから必要な部分のみ...
-
リストの作成と出力(C言語)
-
大量のファイルを読み込み、そ...
-
Ç言語でファイルサイズを変更す...
-
C++で指定文字列のカウント方法...
おすすめ情報