c语言中数据截断的坑
1.数据截断的定义
当目标数据类型的内部存储空间较短时,自动将源数据类型的低位部分作为目标数据类型值的转换过程被称之为
截断
。
例如
char ch=65;
printf("%c\n",ch);
输出结果
A
在这个代码块中我们都知道65是A的相对应的ASCII值,然后当以字符输出时是将整型转化为字符型,在计算机内存中整型与字符型所占的内存大小就不同,因此就会在转换过程中发生截断
2.数据在内存中的存储
在计算机机器语言中-,一切语言都是以二进制的形式存储,而内存中存储的最小单位是bit位。
整数
在机内以
补码
存放。正整数的补码就是它的原码,负整数的补码为反码加1的结果。一般第一位是
符号位
,
1
表示
负号
,
0
表示
正号
。例如:-5
-
原码为:
1
0000000 00000101 -
反码为:
1
1111111 11111010 -
补码为:
1
1111111 11111011
3.实际案例
- 案例1
char ch=90; [00000000 01011010]
—————- [————–01011010]
- [ 整数转换成字符的转换过程] ,小伙伴发现没,最后8位正着写,反着写都是一样的,记住得是反着写!!!!
取
低位部分
作为目标数据类型值的转换
- 案例2
short i=-4;
printf("ASCII=%c\n",i);
输出结果为:ASCII=?
分析: short ,两个字节,16bit位,char,1字节,8bit位。故在此代码中-4的内部存储值为:
原码 | 10000000 00000100 |
---|---|
反码 |
11111111 11111011 |
补码 |
11111111 11111100 |
特别注意这时取低位常犯的坑,
并不是直接取后8位,而是从最后一位往前数8位
,及并不是取
111111100
,而是
00111111
,前一种不对,后一种的ASCII码值算出来就刚好是63,对应的字符就是?当时我想的就是第一种,结果
4.扩展
这儿就简单描述一下
扩展
,它与截断刚好相反,是目标的存储空间比原类型长,而扩展分为符号
扩展
和
零扩展
。符号扩展是对有符号数用原来的符号位进行扩展,零扩展是对无符号数扩展其高位全部为0.
char cA=97,cB=132;
unsigned char arr=97,abb=132;
int i,j,r,b;
i=cA;//最高位为零的符号扩展
j=cB;//最高位为1的符号扩展
r=arr;//最高位为零的无符号扩展
b=abb;//最高位为1的无符号扩展
printf("%d %d %d %d",i,j,r,b);
输出结果:97 -124 97 132
5.总结
数据截断与数据扩展是c语言中的基础知识,有些坑需要注意