免费学习网考试资料计算机类内容页

C语言中的正负数以及数值溢出

2021-04-24 15:46:03 计算机类

  C语言中的正负数以及数值溢出

  在数学中,数字有正负之分。在C语言中也是一样。下面是小编分享的C语言中的正负数以及数值溢出,欢迎大家参考!

  在C语言中,short、int、long 都可以带上符号,例如:

  short a = -10; //负数int b = +10; //正数long c = -9 + +12; //负数和正数相加

  如果不带正负号,默认就是正数。

  符号也要在内存中体现出来。符号只有正负两种情况,用1位就足以表示,这1位就是最高位。以 int 为例,它占用32位的内存,0~30位表示数值,31 位表示正负号。如下图所示:

  在编程语言中,计数往往是从0开始,例如字符串 "abc123",我们称第 0 个字符是 a,第 1 个字符是 b,第 5 个字符是 3。这和我们平时从 1 开始计数的习惯不一样,大家要慢慢适应,培养编程思维。

  在符号位中,用0表示正数,用1表示负数。例如 int 类型的 -10、+16 在内存中的表示如下:

  如果不希望设置符号位,可以在数据类型前面加 unsigned,如下所示:

  unsigned short a = 12;unsigned int b = 1002;unsigned long c = 9892320;

  这样,short、int、long 中就没有符号位了,所有的位都用来表示数值。也就意味着,使用了 unsigned 只能表示正数,不能表示负数了。

  如果是unsigned int,那么可以省略 int ,只写 unsigned,例如:

  unsigned n = 100;

  它等价于:

  unsigned int n = 100;

  输出无符号数使用%u,代码如下:

  #include #include int main int a1 = 1234, a2 = -1234; unsigned int b1 = 5678, b2 = -5678; printf"a1=%d, a1u=%u", a1, a1; printf"a2=%d, a2u=%u", a2, a2; printf"b1=%d, b1u=%u", b1, b1; printf"b2=%d, b2u=%u", b2, b2; return 0;

  输出结果:

  a1=1234, a1u=1234

  a2=-1234, a2u=4294966062

  b1=5678, b1u=5678

  b2=-5678, b2u=4294961618

  可以发现,无论变量声明为有符号数还是无符号数,只有当以 %u 格式输出时,才会作为无符号数处理;如果声明为 unsigned 却以 d% 输出,那么也是有符号数。

  a2、b2 的输出值之所以很奇怪,与它们在内存中的存储形式有关,我们将在《C语言整数在内存中是如何存储的》一节详细介绍。

  最后需要说明的是:不管是否有符号,%o、%x、%X、%#o、%#x、%#X 都是以无符号形式输出,读者可以亲自测试。

  取值范围和数据溢出

  short、int、long 占用的字节数不同,所能表示的数值范围也不同。以32位平台为例,下面是它们的'取值范围:

数据类型所占字节数取值范围short2-32768~32767,即 -215~215-1unsigned short20~65535,即 0~216-1int4-2147483648~2147483647,即 -231~231-1unsigned int40~4294967295,即0~232-1long4-2147483648~2147483647,即 -231~231-1unsigned long40~4294967295,即0~232-1

  当数值过大或过小时,有限的几个字节就不能表示,就会发生溢出。发生溢出时,最高位会被截去。请看下面的例子:

  #include int main unsigned int a = 0x100000000; int b = 0xffffffff; printf"a=%u, b=%d", a, b; return 0;

  运行结果:

  a=0, b=-1

  变量 a 为 int 类型,占用4个字节32位,能表示的最大值为 0xFFFFFFFF,而 0x100000000 = 0xFFFFFFFF + 1,占用33位,已超出 a 所能表示的最大值,会发生溢出,最高位被截去,剩下的32位都是0。也就是说,在 a 被输出前,其值已经变成了 0。

猜你可能喜欢