C语言中数据类型的表示范围

问题:sizeof(int) = 2,int的表示范围为什么是-2^15~2^15-1?

答:对于有符号数,最高位为符号位。二进制原码最大值为0111111111111111=2^15-1,最小值为 1111111111111111=-(2^15-1),而0分为+0和-0,即0000000000000000和

1000000000000000。所以,当以二进制原码表示时,int的表示范围是-32767~-0和+0~32767。注意+0等于-0,因而表示范围中不同的数值个数有2^16-1个,比16位二进制能够提供的2^16个编码少1个。

但计算机中是采用二进制补码存储数据的。正数编码不变,即从0000000000000000到0111111111111111,范围是0~2^15-1。负数编码需要把除符号位以后的部分取反加1。

-32767的补码为1000000000000001,-0的补码为0000000000000000。注意到+0和-0在补码系统中的编码是一样的,而16位二进制数可表示2^16个编码,在补码中零的编码只有一个(+0和-0的编码一样),所以补码中会比原码多一个编码出来,这个编码就是1000000000000000。因为任何一个原码都不可能在转成补码时变成1000000000000000,所以,人为规定1000000000000000这个补码编码为-32768。所以,int的表示范围在补码系统中是-32768~32767。

注意,二进制的最小值确实是1111111111111111,只是二进制补码的最小值才是1000000000000000。


下面举几个容易错的例题。

#include <stdio.h>
int main(void) 
{ 
    char ch = 127;
    ch += 1;
    printf("%d\n", ch);		//结果是-128
	
    return 0; 
}
结果为:-128。char的表示范围是-128~127。因为127 + 1 = 128,二进制表示为10000000,对于有符号的ch来说,最高位为1表示负数。

#include <stdio.h>

int main(void) 
{ 
    unsigned char ch = 255;
    ch += 1;
    printf("%d\n", ch);		//结果是0
	
    return 0; 
}

    结果为:0。ch = 255在计算机中的存储为:(000....)11111111,(000....)11111111+1 = (000...)0001 00000000,然后再将最后八位二进制截取给ch,由于最后八位全是0,因此ch = 0。

     对于unsigned类型来说,编译器必须调整越界值使其满足要求。编译器会将该值对unsigned类型的可能取值数目求模,然后取所得值。例如:8位的unsigned char其取值范围从0到255,将336存储到8位的unsigned char中,则实际赋值为80,因为336 mod 256 = 80。负数总是超出取值范围,有些语言将负数赋给unsigned类型是非法的,但在C++中是合法的,其结果是该负数对该类型的取值个数求模后的值。例如:将-1赋给8位的unsigned char,结果是255,因为-1 mod 256 = 255。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值