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,

a1(u)=%u\n", a1, a1);

printf("a2=%d,

a2(u)=%u\n", a2, a2);

printf("b1=%d,

b1(u)=%u\n", b1, b1);

printf("b2=%d,

b2(u)=%u\n", b2, b2);

return 0;

}

输出结果:

a1=1234, a1(u)=1234

a2=-1234, a2(u)=4294966062

b1=5678, b1(u)=5678

b2=-5678, b2(u)=4294961618

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

却以 d% 输出,那么也是有符号数。

a2、b2 的输出值之所以很奇怪,与它们在内存中的存储形式有关。

最后需要说明的是:不管是否有符号,%o、%x、%X、%#o、%#x、%#X

都是以无符号形式输出,读者可以亲自测试。

取值范围和数据溢出

short、int、long

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

数据类型 所占字节数 取值范围

short 2 -32768~32767,即 -215~(215-1)

unsigned short 2 0~65535,即 0~(216-1)

int 4 -2147483648~2147483647,即 -231~(231-1)

unsigned int 4 0~4294967295,即0~(232-1)

long 4 -2147483648~2147483647,即 -231~(231-1)

unsigned long 4 0~4294967295,即0~(232-1)

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

#include

int main()

{

unsigned int a =

0x100000000;

int b =

0xffffffff;

printf("a=%u, b=%d\n",

a, b);

return 0;

}

运行结果:

a=0, b=-1

变量 a 为 int 类型,占用4个字节(32位),能表示的最大值为 0xFFFFFFFF,而 0x100000000 =

0xFFFFFFFF + 1,占用33位,已超出 a 所能表示的最大值,会发生溢出,最高位被截去,剩下的32位都是0。也就是说,在 a

被输出前,其值已经变成了 0。

对于变量 b,每一位的值都是 1,包括符号位,以 %d 输出时,按照推理应该是 -0x7fffffff =

-2147483647,但是输出结果却是 -1。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值