C++的变量类型大家都十分熟悉,主要是bool,char,int,long,double等。这些基本类型中有的可以用关键字signed和unsigned进行修饰。
signed和unsigned关键字修饰的变量的区别在于最高位是否充当符号位存在。经过unsigned关键字修饰后的变量类型,因为最高位不再充当符号位而是用来存储数值,因此可表示的最大数字会比signed要大。比如,8位signed char能表示的范围是从-128~127而unsined char能表示的范围则是0~255。
默认情况下int,short,long 和 long long类型都是默认为signed的。因此,如果需要使用unsigned类型需要特别声明,即在声明时类型名前加上关键字unsigned,如unsigned int。
但是char的情况就比较特殊。事实上会有char,signed char,unsigned char三种类型。虽然说有三种,但char实际上会等同于另外两种当中的一种。至于char到底会和哪一种等价则取决于编译器。
unsigned可以帮我们增大数值类型的最大可表示的数字,但是使用unsigned进行算数时需要注意一些细节。
当我们使用unsigned和int类型的两个变量进行算数运算时,int类型的变量会自动转换成unsigned。因此,如果Int类型变量的数字表示的是一个负数,那么运算结果会出错。例如:unsigned a = 10; int b = -42; b + b的数值会是正常的-84。而a + b的值则会是一个极大的数字,具体数值会因不同编译环境 int 所占字节的不同而变化,在int占32位的环境下,这个值会是4294967264。这很明显是错误的,而造成这一错误的原因就是身为int类型的 b 被转换为unsigned ,使得最高位的符号位1作为数值大小而存在造成的。
再看另一个我们十分熟悉的语句 for(unsigned u = 10; u >=0; u--);这种循环语句大家都十分熟悉,只是循环变量类型从大家熟悉的int变成了unsigned。这样一个小变化乍看之下没有问题,实际上会导致这个循环从一个普通的循环变成死循环。这个循环的退出条件是当u < 0的时候,可是当u要减至-1时,因为变量类型是unsigned, -1 并无法作为unsigned变量存在,因此该变量会再度变为一个极大的数值,因此u会永远无法小于0,从而使得该循环永远无法结束。
综上,unsigned 类型为我们扩大了数值能表示的最大范围,但是如果在运算时的两个变量类型分别为unsigned 类型的变量和signed类型,signed类型的变量会转换为unsigned类型,这在一些情况下会导致我们程序的运算结果错误,需要额外留意。
本文章参考书籍为 C++ PRIMER 第5版