C语言中的有符号数和无符号数

认识有符号数和无符号数 

  说起有符号数和无符号数,就不得不提到原码、反码和补码,那我们就从他们开始说起吧。

  一个数在计算机中的二进制表示形式,  叫做这个数的机器数,机器数是以补码形式储存在计算机中的。但是仅仅存储一个补码,计算机是怎么知道它存的是一个正数还是一个负数呢?计算机用一个数的最高位存放了它的符号,‘0’代表正数,‘1’代表负数。不过这个答案是建立在该数字被默认是有符号的基础上的,大多数语言都会把机器数默认是有符号的,比如C 和 C++,还有 java 。但不同的是 C 和 C++不仅支持有符号数而且支持无符号数, java 只支持有符号数。

  通常,大多数数字都被默认为是有符号的,要想创建一个无符号的常量,必须加上后缀字符 ‘U‘ 或 ‘u‘。例如,12345U 或者 0x1A2Bu.

有符号数和无符号数之间的转换

  C语言允许在有符号数和无符号数之间做强制类型转换,例如下面的代码:

C语言中的有符号数和无符号数
1 short int v = -12345;
2 unsigned short uv = (unsigned short) v; 
3 printf ("v = %d , uv = %u\n" , v , uv);   //当用printf输出数值时,分别用指示符 %d ,%u ,%x 以有符号十进制,无符号十进制和十六进制格式输出一个数字
C语言中的有符号数和无符号数

  输出结果:  v = -12345 , uv = 53191 ;     为什么会得到这样的输出结果呢?我们不妨分析一下:

    “-12345”的16位补码形式是 1100 1111 1100 0111,

    ”53191”的16位补码形式也是 1100 1111 1100 0111,这就是补码相同,解释方式不同造成的结果。

  由此我们可以得出一个结论,强制类型转换的结果保持不变,只是改变了解释这些位的方式,数值可能会改变,但是位模式不变。

含有符号数和无符号数的运算规则

  当执行一个运算时,如果它的一个运算数是有符号的而另一个是无符号的,那么C语言会隐式地将有符号参数强制类型转换为无符号数。例如 ,-1<0U比较式,因为第二个运算数是无符号的,第一个运算数就会被隐式地转换为无符号数,因此表达式就等价于 4292967295U < 0U ,所以表达式的值为 false.(-1按补码形式存储在计算机中,然后按照无符号数转换成值4292967295,相当于补码忽略最高位的1,全部按照位权值转换)

 

总结:其实我们平时很少会碰到无符号数,但是理解有符号数和无符号数能帮助我们更好的理解数值与机器数之间的关系。

  

  注:本文整理自《深入理解计算机系统》.

 

 

 

 

 

C语言中的有符号数和无符号数,布布扣,bubuko.com

C语言中的有符号数和无符号数

上一篇:java collection.sort()根据时间排序list


下一篇:C++ Vector用法