养成思考的习惯分析这两段代码的结果
void test()
{
char i = -10;
unsigned int j = 5;
printf("%d",i+j);
}
void test()
{
char i = -10;
unsigned int j = 5;
printf("%u",i+j);
}
为什么几乎相似代码得到数相差这么大?
关键在于读取方式不一样%d以有符号方式读取而%u以无符号方式读取,本质上i+j在内存中是相同的它们的和以二进制形式存在是1000 0000 0000 0000 0000 0000 0000 0101,如果以有符号形式读取最高位为1为负所以结果自然而然是-5,而以无符号方式读取没有符号位最高位也是数值位所以结果是4294967291
void test()
{
char i = -10;
//原:10000000000000000000000000001010
//反:11111111111111111111111111110101
//补:11111111111111111111111111110110
//补截断:11110110
//相加i类型自动转换为unsigned int且char默认为有符号数所以补1
unsigned int j = 5;
// 00000000000000000000000000000101
// + 11111111111111111111111111110110
//------------------------------------------
//和补:11111111111111111111111111111011
//
//和原: 10000000000000000000000000000101
printf("%d",i+j);//%d以有符号整型读取
printf("\n");
printf("%u", i + j);
}
再分析以下这两段代码
void test3()
{
unsigned char i = -10;
unsigned int j = 5;
printf("%d", i + j);
}
void test4()
{
char i = -10;
int j = 5;
printf("%d", i + j);
}
这时i+j在内存中已经不同了test3中i+j为0000 0000 0000 0000 0000 0000 1111 1011
void test3()
{
unsigned char i = -10;
//原:10000000000000000000000000001010
//反:11111111111111111111111111110101
//补:11111111111111111111111111110110
补截断:11110110
unsigned int j = 5;
// 00000000000000000000000000000101
// +
// 00000000000000000000000011110110(i的类型自动转换结果)
//--------------------------------------------
// 00000000000000000000000011111011
printf("%d", i + j);
}
而在test4中i+j为?10000000000000000000000000000101
void test4()
{
char i = -10;
//原:10000000000000000000000000001010
//反:11111111111111111111111111110101
//补:11111111111111111111111111110110
//补截断:11110110
int j = 5;
// 00000000000000000000000000000101
// + 11111111111111111111111111110110
//------------------------------------------
//和补:11111111111111111111111111111011
//
//和原: 10000000000000000000000000000101
printf("%d",i+j);//%d以有符号整型读取
}
这是因为它们存的模式改变,在创建变量之前我们会声明类型根据类型开辟空间,在整型提升时根据是否有无符号补0还是1,如果是无符号数就算原数最高位是1也补0,如果是有符号数看最高位。
总结:取得方式不同得到结果不同,声明类型不同开辟空间不同运算规则也不同。
补充关于类型转换