アプリ版:「スタンプのみでお礼する」機能のリリースについて

C言語に関しての質問です。
以下のようなプログラムでは変数bをキャストした場合と
しない場合で条件式の判定結果が違います。
変数bはもともとunsiged char型なのでキャストは不要だと
思ったのですが、なぜ結果が違うのでしょうか?
(条件式if(a != ~b)の判定結果も偽になることを期待していました。)

unsigned char a;
unsigned char b;

a = ~0x98;
b = 0x98;

if(a != ~b)
{
printf("こっちは入る");
}

if(a != (unsigned char)(~b))
{
printf("こっちは入らない");
}

A 回答 (6件)

C言語とのことなので、C++で検証しても、参考にはなっても結論にはたどりつけませんね。



今回のコードについては処理系によって振る舞いが変わります。
sizeof(char) < sizeof(int) の処理系であれば、unsigned char型のbに~演算子を適用する前に整数拡張が起こり、結果としてint型になります。
sizeof(char) == sizeof(int) の処理系であれば、整数拡張の結果 unsigned int型になりますが、unsigned charとunsigned intの表現範囲が同じなので、キャストしてもしなくても結果は同じになるはずです。
    • good
    • 0

>sizeof(char) == sizeof(int) の処理系であれば


> こういう処理系は、あるのでしょうか?

使ったことがあります。
テキサスインスツルメンツのDSP用のCでは char が16ビットです。
sizof(char)もsizeof(int)も値は1でした。
sizof(char)が1なのは規格で決まっているからですね。

PIC用の CCS-Cでは intは8ビットです。
    • good
    • 0

No.2の方のお話を参考にどういう動きが起こってるのか書いてみました。


int型を4バイトとして考えます。

unsigned char a;
unsigned char b;

a = ~0x98;
b = 0x98;
ここでは2進数で考えてみます。
aとbにはそれぞれ
a ← 01100111
b ← 10011000
が格納されます。

if(a != ~b)
この式でaとbが整数拡張されるので
a ← 00000000 00000000 00000000 01100111
b ← 00000000 00000000 00000000 10011000
更にbはビット反転しますので、
~b ← 11111111 11111111 11111111 01100111
となり、aと~bが異なるのでif文内の条件式が真となります。

if(a != (unsigned char)(~b))
ここでもaとbに整数拡張が起こり
a ← 00000000 00000000 00000000 01100111
b ← 00000000 00000000 00000000 10011000
~b ← 11111111 11111111 11111111 01100111
ここで~bがunsigned char型にキャストされますので、
上位24ビットがカットされ
(unsigned char)(~b) ← 01100111
この状態でaと~bを比較します。
値はaもbも同じになり、if文の条件式が偽となります。

こんな感じで合ってますかね。
    • good
    • 0

> こういう処理系は、あるのでしょうか?



実在します。
    • good
    • 0

>sizeof(char) == sizeof(int) の処理系であれば



こういう処理系は、あるのでしょうか?
    • good
    • 0

んー、気にしたことありませんでしたがそうなんですね。


検証してみたVC++用適当ソース(gccならtypeof?)。C++だけどそこは気にしない方針で。
-------------------------------------------------------
#include <stdio.h>
#include <typeinfo>

int main() {
unsigned char a, b;
a = ~0x98;
b = 0x98;
printf("%d, %d\n", a, ~b); // 103, -153
printf("%s\n", typeid(~b).name()); // int
printf("%d, %d\n", a, unsigned char(~b)); // 103, 103
printf("%s\n", typeid(unsigned char(~b)).name()); // unsigned char
}
-------------------------------------------------------
つまり~bはint型になる=負値になっているわけですね。
しらなかった。
    • good
    • 0
この回答へのお礼

わざわざ検証していただきありがとうございますm(_ _)m
なるほど~、int型になっていたのですね。
そのような検証方法があることも勉強になりました。

お礼日時:2009/09/05 05:07

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!