您的位置:首页 > 其它

Type conversion - unsigned to signed int/char

2014-02-17 12:42 357 查看
Q:

I tried the to execute the below program:

#include <stdio.h>

int main() {
signed char a = -5;
unsigned char b = -5;
int c = -5;
unsigned int d = -5;

if (a == b)
printf("\r\n char is SAME!!!");
else
printf("\r\n char is DIFF!!!");

if (c == d)
printf("\r\n int is SAME!!!");
else
printf("\r\n int is DIFF!!!");

return 0;
}

For this program, I am getting the output:

char is DIFF!!! int is SAME!!!

Why are we getting different outputs for both?
Should the output be as below ?

char is SAME!!! int is SAME!!!


A1:

This is because of the various implicit type conversion rules in C. There are two of them that a C programmer must know: the
usual arithmetic conversions and the integer promotions (the latter are part of the former).

In the char case you have the types 
(unsigned
char) == (signed char)
. These are both small integer types. Other such small integer types are 
bool
 and 
short
.
The integer promotion rules state that whenever a small integer type is an operand of an operation, its type will get promoted to 
int
,
which is signed. This will happen no matter if the type was signed or unsigned.

In the case of the 
signed
char
, the sign will be preserved and it will be promoted to an 
int
containing
the value -5. In the case of the 
unsigned
char
, it contains a value which is 251 (0xFB ). It will be promoted to an 
int
 containing
that same value. You end up with
if( (int)-5 == (int)251 )

In the integer case you have the types 
(unsigned
int) == (signed int)
. They are not small integer types, so the integer promotions do not apply. Instead, they are balanced by the
usual arithmetic conversions, which state that if two operands have the same "rank" (size) but different signedness, the signed operand is converted
to the same type as the unsigned one. You end up with

if( (unsigned int)-5 == (unsigned int)-5)


A2:

Cool question!

The 
int
 comparison
works, because both ints contain exactly the same bits, so they are essentially the same. But what about the 
char
s?

Ah, C implicitly promotes 
char
s
to 
int
s
on various occasions. This is one of them. Your code says
if(a==b)
,
but what the compiler actually turns that to is:

if((int)a==(int)b)

(int)a
 is
-5, but 
(int)b
 is
251. Those are definitely not the same.

EDIT: As @Carbonic-Acid pointed out, 
(int)b
 is
251 only if a 
char
 is
8 bits long. If 
int
 is
32 bits long, 
(int)b
 is
-32764.

REDIT: There's a whole bunch of comments discussing the nature of the answer if a byte is not 8 bits long. The only difference in this case is that 
(int)b
 is
not 251 but a different positive number, which isn't -5. This is not really relevant to the question which is still very cool.
From:http://stackoverflow.com/questions/17312545/type-conversion-unsigned-to-signed-int-char
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐