金秀有什么好玩的地方:一个经常被忽略的c语言问题

来源:百度文库 编辑:神马品牌网 时间:2024/05/02 04:32:34
c语言无符号数和有符号数运算得到什么样的结果
int main()
{
int a=6;

unsigned int b=-20;

(a+b>6)?puts(">6"):puts("<=6");

return 0;

}
该函数返回〉6为什么呀??
如果把unsigned a=6;int b=12
结果为什么 还是错误的

变量b本来是unsigned型变量,它是个非负数,你偏偏把-20赋给了它,当然会出错。
把负数赋给一个unsigned型变量将会发生溢出。
unsigned型变量的取值范围为0~65536,如果赋给它的值不在这个范围内,则会把这个值加上或减去N个65536,使得这个值还是在0~65536的范围内,这就是溢出!
你把-20赋给unsigned型变量b,它会加上65536把这个数调整到0~65536的范围内,所以b的值是-20 + 65536 = 65516

因此,a + b 当然大于 6 了!!

编译器是不会加65536的,其实内存存储的都是一样的,
-20就是FFEC,也就是1111 1111 1110 1100,这样有符号就是-20,无符号就是65516。
编译器会尽可能用一个合适的类型去存放a+b,
所以你没有把a+b的值赋值给一个特定类型的变量时,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
它的结果就是无符号的,所以会大于6,如果你写成
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int temp = a+b;
(temp>6)?puts(">6"):puts("<=6");
则应该会输出<=6

所以你改成unsigned a = 6; int b = -12;也没用

4: int a=6;
00401028 mov dword ptr [ebp-4],6
5:
6: unsigned int b=-20;
0040102F mov dword ptr [ebp-8],0FFFFFFECh
7:
8: (a+b>6)?puts(">6"):puts("<=6");
00401036 mov eax,dword ptr [ebp-4]
00401039 add eax,dword ptr [ebp-8]
0040103C cmp eax,6

这是程序在vc下反汇编的片段,c语言混合运算遵循自动类型转换由低数据类型向高数据类型转换,即char,short->int->unsigned->long->double<-float
-20=0FFFFFFECh在无符号变量范围内,所以b接收-20时-20自动转换成无符号数值即0FFFFFFECh
a+b=0FFFFFFECh+6=0fffffff2h>6,期间运算无溢出

可能是结果因为是负值,而加了一个65535,所以得不到接过了吧

同意DannyPotter。