int main(void)
{
for (int i = -1; i < sizeof(int); i++) {
printf("%d\n", i);
}
return 0;
}
啥都不输出,因为:
1、sizeof()返回的是unsigned int类型
2、有符号数与无符号数进行运算时,有符号数先自动转换成无符号数
因此"i < sizeof(int)"比较时-1会转换成unsigned int类型,溢出到unsigned int的最大值,导致大于sizeof(int)
int main(void)
{
unsigned int a = 6;
int b = -20;
int c = a + b;
printf("b = %u\n", b); // b = 4294967276
printf("a + b = %u\n", a + b); // a + b = 4294967282
printf("a + b = %d\n", a + b); // a + b = -14
if ((a + b) > 0) {
printf("a + b > 0\n"); // a + b > 0
} else {
printf("a + b <= 0\n");
}
if (c > 0) {
printf("c > 0\n");
} else {
printf("c <= 0\n"); // c <= 0
}
return 0;
}
1、a+b,b要转为无符号,即4294967276,可以理解为无符号下-20,
再加a就是4294967282,即ffff fff2,可以理解为无符号下-14,因此输出回%d有符号十进制就是-14
2、a+b的值是ffff fff2,肯定大于0,所以输出a + b > 0
3、c是int类型有符号整数,所以同%d输出一样,无符号下-14值转有符号十进制是-14,所以c小于0
int main(void)
{
signed short i = 65535;
printf("%d\n", i);
return 0;
}
i为-1。因为short占2字节,所以是16位,
short最大值为0111 1111 1111 1111,为32767
short最小值为1000 0000 0000 0000,首位为符号位,1代表负数所以得转为原码
首位符号位取反,其余所有位也取反后最后一位加1
即0111 1111 1111 1111 + 1 = 1000 0000 0000 0000即32768,所以该负数的原码为32768,该负数为-32768
65535比32767溢出32768,而溢出1就是-32768,因此溢出32768偏移32767就是-32768+32767=-1。
总结,无符号数与有符号数的运算原则如下:
1、参与运算的类型不同,会自动转换成相同类型再运算。
2、转换的方向为向数据长度增长的方向,char->short->int->unsigned int ->long
3、所有float都会先转成double进行运算,哪怕只有一个float
4、赋值运算时,赋值号右边的类型向左边的类型转换。
5、浮点数和整形数,整形数向浮点数转换。
6、在表达式中,如果char和short类型的值进行运算,无论char和short有无符号,结果都会自动转换成int。
7、如果char或short与int类型进行计算,结果和int类型相同。即:如果int是有符号,结果就是带符号的,如果int是无符号的,结果就是无符号的。