寻高手解决C中的unsigned类型数值问题
unsigned b=-1;//理论上似乎不该有这样的初始化。printf出来的b=-1
我的推理过程
==>假设上面初始化合法,我们把-1的补码存储到内存中,因为我们标记内存地址为&b的数为无符号整形,所以断点监视时,监测出一个大数(这个大数似乎跟内存存在一定的关系,而不仅是单纯的CPU字长)
==>当调用printf函数时,printf根据取到的数先对符号位进行判断,发现符号位为1,是负数,所以求出取出来的数的补码,得到-1
==>假设上面的推理成立,即断点监视和printf有自己一套判断一个数的方法,尽管有些荒谬。。。
==>我重定义了个整形变量:int a=65530;超出了int的可表示范围。。。。发现了个问题。。
==>内存全到这个数似乎仅给它标记为int类型数据,并不检查范围,只是简单的计算a的补码,并存储起来,高位按0填充。。。
==>断点监视和printf时发现是个正数,直接输出65530
本想用第二个初始化推倒上面的假设,,,却没法得到矛盾。。。
从上面似乎可以得出:int和unsigned似乎不再是C语言中简单的2个字节了,,,而已经被CPU字长和内存所影响。。。。
[解决办法]
存储的二进制不会变,-1对二进制位32个1(编译的unsigned和int是4字节的);那么对unsigned的值为4294967295;对int为负一;
看你printf是按什么格式输出%d还%u;
tmp.c:
int main(int argc, char *argv[])
{
int d = 4294967295;
printf("%d\n", d);
return 0;
}
[root@localhost11 tmp]# gcc tmp.c -o tmp -Wall
tmp.c: 在函数 ‘main’ 中:
tmp.c:16: 警告:这个小数常量仅 ISO C90 中是无符号的
[root@localhost11 tmp]# ./tmp
-1
如果改为%u输出,为4294967295;