大部分程序对无符号数类型的使用可能不是很频繁(实际上,仅C/C++等少数语言支持unsigned类型)。但是,unsigned到signed的隐式强制转换常常会导致程序错误与漏洞,比较著名的一个案例就是:函数getpeername的安全漏洞。
<span style="font-size:18px;"> unsigned int i=3; cout<<i*-1; </span>问输出是多少?
1、unsigned int和int类型的数据大小均为4字节,即32位。(无论是32位字长机器还是64位字长机器)2、机器一般都是用补码表示有符号数。3、有符号数到无符号数的转换规则:位值保持不变,只改变解释这些位值的方式。
知识补充:为什么 1111...1111 (32个1)表示-1?
注意,因为是补码,所以规定最高位的权重是负的,其他位的权重是正的,这样计算出来的数就表示有符号数。
int可以表示的范围是 -2^31~2^31-1,十六进制0x80000000~0x7fffffff,十进制-2147483648~2147483647
#3:运算
4294967295*3=12884901885,而unsigned int的表示范围为0~2^32-1,12884901885超出了该范围。
C语言中规定这种情况要采取模运算,即将无符号乘积模2^32(取余)
12884901885 mod 2^32 = 4294967293,相当于取乘积的低32位,将其写成十六进制形式会更加明显:0x2FFFFFFFD mod 0xFFFFFFFF = 0xFFFFFFFD
<span style="font-size:18px;">float array_sum(float a[],unsigned length) { int i; float sum=0; for(i=0;i<=length-1;i++) sum+=a[i]; return sum; }</span>
<span style="font-size:18px;">/*strlen函数原型*/ size_t strlen(const char *s); /*长度比较函数*/ int strlonger(char *str1,char *str2) { return strlen(str1)-strlen(str2)>0; }</span>