short变量的值超过范围
在C语言中整数是用补码的形式进行存储。不同整数类型占据不同的内存空间。
比如:short型变量占据2B,表示的数据范围是-32768~32767,在 这个范围内可以进行正常的数值运算。
但是如果不小心让short变量的值超过这个范围,会如何?
short m;
m=32768;
printf("%d",m);
十进制32768在内存存储为1000 0000 0000 0000。
执行printf("%d",m);,编译器便到内存找到m对应的值1000 0000 0000 0000。接下来它这样做:
开头是1,是负数;然后减1,各位取反,得到1000 0000 0000 0000,将其转为十进制,是32768。于是m=-32768。
再举个例子
short m;
m=-32769;
printf("%d",m);
会输出什么?
首先,-32769在内存中是什么样的?1000 0000 0000 0001or0111 1111 1111 1111?
负数存的是它的补码,-32769的补码是后者。
接着要执行printf("%d",m);了,编译器从内存找到变量m的值0111 1111 1111 1111。
编译器是这样处理的:开头是0,是正数。直接将其转为十进制,便是32767。
signed short类型转为unsigned short
我们在学到类型转换的时候,无符号的优先级大于有符号的。如:一个signed int+unsigned int结果是unsigned int型,即signed int会先转为unsigned int,然后再运算。
有符号和无符号的存储范围不一样,如:
| signed short | -32768~32767 |
|---|---|
| unsigned short | 0~65,536 |
short m=32768;
unsigned short n;
n=m;
printf("n=%d",n);
32768存为1000 0000 0000 0000。
编译器取到这个数据后怎么做?和上面步骤一样,但是第一步省略,即不判断正负,直接转为十进制。所以n和m的值相同。
short m=-32769;
unsigned short n;
n=m;
printf("n=%d",n);
输出什么?

short类型转为int类型
short是2B,int是4B,内存空间不一样。将short转为int,如果是:0101 1111 1011 0000,则会转为0000 0000 0000 0000 0101 1111 1011 0000;如果是1101 1111 1011 0000,则会转为:1111 1111 1111 1111 1101 1111 1011 0000。本质就是,第一位是0,那么前面补两个字节的0;第一位是1,前面补两个字节的1。
我们用强制转化换测试一下
short m=24496;
printf("%d",(int)m);
m在内存存为:0101 1111 1011 0000
(int)m,那么0101 1111 1011 0000就变成了0000 0000 0000 0000 0101 1111 1011 0000
所以输出和原来一样,只是占据的内存量变大了2B。
再看个例子
short m=-32770;
printf("%d",(int)m);
输出什么?
是-32770吗?
分析一下:
-32770在内存以补码形式存储,存储内容为:0111 1111 1111 1110
0111 1111 1111 1110存在4B的空间中变成了0000 0000 0000 0000 0111 1111 1111 1110
0000 0000 0000 0000 0111 1111 1111 1110第一位是0,故直接转为十进制,是32766。
这里容易造成的误解是,认为int的范围比short大,那么超过short范围的数值可以当做正常的int数据,所以认为-32770变成int型后可以输出-32770。
但看了内在的机制后便不会这样认为了。
类型转换中的误解
short型数据和short型数据进行四则运算,结果是int型。

输出是4,说明a+b这个表达式的结果是int型,因为short型是输出2.
编译a+b ,会先将a,b转为int型,然后再进行加法。
但是之后a和b是什么类型,int吗?

其实还是short。这便是容易产生误解的地方。自动类型转换和强制类型转换只是在运算时进行转,但是不会改变变量本来的类型。
Over!
7501

被折叠的 条评论
为什么被折叠?



