
C言語初心者です。
unsigned int型に関する質問です。
---------------------------------
#include <stdio.h>
int main(void) {
unsigned int in1 = 10;
unsigned int in2 = -10;
unsigned char ch1 = 10;
unsigned char ch2 = -10;
printf("in1 = %d\n", i);
printf("in2 = %d\n", i);
printf("ch1 = %d\n", ch1);
printf("ch2 = %d\n", ch2);
return 0;
}
---------------------------------
上記のプログラムを作成して実行すると、結果は以下の通りです。
[実行結果]
in1 = 10;
in2 = -10;
ch1 = 10;
ch2 = 246;
変数in2の値を表示した結果に関してですが、
unsigned int型にも関わらず負の値「-10」が表示されるのは
何故でしょうか?
No.3ベストアンサー
- 回答日時:
他の回答者さんの通りですが、補足したいと思います。
C の printf() 関数は、他の関数(正確には引数の個数が決まっている普通の関数)とはすこし勝手がちがいます。
どう違うかというと、printf() で format に続く引数の型がどうなっているかは、printf() が呼び出されて printf() が fomrat を調べて始めて分かります。ここで「分かる」と言いましたが、どういう型なのかは format に "%d" だと int 型の引数がある、と思い込んでいるだけなので、そうでない型が来ていても、そのまま何も考えずに表示しようとします。
gcc でコンパイルすると型が違った場合、コンパイル時にチェックして警告が出たりします(ただし -Wall などの警告オプションを付けた時)。
ですから、極端な話、
char *p;
printf( "%d\n", p );
とやってもちゃんと動作しますが、出力された数値はとんでもない数字になります。つまりポインタを符号付き整数だと思い込んで出力しているのです。
ということで、質問者さんの場合では、printf() の format に "%u" としてして「ここの引数は符号無し整数だよ」と教える必要があります。
No.6
- 回答日時:
printfでformatに%dを指定して、符号ありの整数として出力しているから。
符号なし整数で表示する場合は%uです。
32bitの変数で-10は0xfffffff6です。
(意味が解からなければ補数とかで調べて下さい。)
だからin2には0xfffffff6っていう数値が入ってます。
これを符号ありの整数として扱うと-10です。
符号無しの整数として扱えば4294967286です。
試しに
unsigned int in2 = 4294967286;
や、
unsigned int in2 = 0xfffffff6;
に書き換えて試してみてください。
同じ結果が得られることでしょう。
unsignedと宣言している以上、-10を代入するなんてことは普通はやっちゃダメです。
No.5
- 回答日時:
#4です。
訂正。汎整数拡張では、負数の変換についても正式に定義されているんですね。
ということは、
>unsigned int in1 = 10;
in1=10
>unsigned int in2 = -10;
in2= -10 + ( UINT_MAX + 1 ) = -10 + (4294967295+1)=4294967286
>unsigned char ch1 = 10;
ch1=10
>unsigned char ch2 = -10;
ch2= -10 + ( UCHAR_MAX +1 )= -10 + ( 255 + 1 ) = 246
であって、
>printf("in1 = %d\n", i);
unsigned intからintへの変換で、intで表現可能なので、10と表示
>printf("in2 = %d\n", i);
unsigned intからintへの変換で、intで表現不可能なので、処理系定義
>printf("ch1 = %d\n", ch1);
unsigned charを引数に渡すときにintに変換、intで表現可能なので、10のまま。
intで表示しようとするので、10と表示
>printf("ch2 = %d\n", ch2);
unsigned charを引数に渡すときにintに変換、intで表現可能なので、246のまま。
intで表示しようとするので、246と表示
ということですね。
ということで、
>printf("in2 = %d\n", i);
が間違い(処理系依存)ということですか。
#intが32bit,char が8bitで考えています。
No.4
- 回答日時:
>変数in2の値を表示した結果に関してですが、
> unsigned int in2 = -10;
unsignedに負の値を代入しているし、
> printf("in2 = %d\n", i);
unsigned intの値を%dで表示しようとしている。
つまり間違ったプログラムだから。「-10」が表示されたのはたまたまに過ぎません。
ちなみに、この中で正しいのはch1だけのはず。
No.2
- 回答日時:
> unsigned int型にも関わらず負の値「-10」が表示されるのは
> 何故でしょうか?
"%d" は signed int として扱うからです。
"%u" とすれば unsigned int として扱われます。
コード
printf("in1 = %u\n", in1);
printf("in2 = %u\n", in2);
printf("ch1 = %u\n", ch1);
printf("ch2 = %u\n", ch2);
結果
in1 = 10
in2 = 4294967286
ch1 = 10
ch2 = 246
printf のフォーマットについて調べてみてはいかがでしょうか?
No.1
- 回答日時:
printfの変換指定子"%d"で符号なしから符号ありへ型が変換されたためでしょう
変数の型と表示の型を合わせるなら
printf("in1 = %d\n", in1);
printf("in2 = %u\n", in2);
printf("ch1 = %hhd\n", ch1);
printf("ch2 = %hhu\n", ch2);
としましょう
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
三角形の判別
-
プログラミングについて質問で...
-
c言語でAからZまでを表示する...
-
10個出力で改行したいのですが...
-
srand(time(NULL))の使い方
-
ピラミッド表示プログラム。
-
C言語 タイマーのソースについて
-
cshの文字列操作(0埋め)
-
Cプログラム
-
C言語プログラミングで「コマン...
-
C言語でマウス入力(クリックや...
-
関数について
-
テキストカーソル位置の取得
-
改行について 1行に何個かづ...
-
CPU温度・負荷等を調べるには
-
scanfに文字が入力されたときに...
-
再帰呼び出しで求めたい経路を...
-
空Enterの扱い方
-
C言語です
-
コマンドラインに出力した文字...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
10個出力で改行したいのですが...
-
c言語でAからZまでを表示する...
-
(C言語)めちゃくちゃな値にな...
-
コマンドラインに出力した文字...
-
コンパイルエラーについて
-
コマンドプロンプトがすぐ消える
-
勝率をプログラムに
-
テキストカーソル位置の取得
-
三角形の判別
-
【C言語教えてください】sin波...
-
4の倍数を論理演算で表す。。
-
C言語で、「自然数nを入力し、n...
-
入力したお金の金額からお札の...
-
cshの文字列操作(0埋め)
-
switch分のケースを範囲数?に...
-
scanfに文字が入力されたときに...
-
プログラミングについての質問です
-
unsigned int型について
-
ダブルポインタで2次元配列を作成
-
円の面積を求めるプログラミン...
おすすめ情報