c语言_Day26_07_27
c语言_Day26_07_271、数据存储
1、整数存储
练习一:
int main()
{
char a = -1;
signed char b = -1;
unsigned char c = -1;
printf("%d %d %d\n", a, b, c);
return 0;
}分析:
-1在内存中转换为补码,即为1111 1111 1111 1111 1111 1111 1111 1111
由于定义字符类型进行保存,故保存为1111 1111
有符号字符:整型提升,高位补符号位,即为1111 1111 1111 1111 1111 1111 1111 1111
转换为原码为-1
无符号字符:整型提升,高位补零,即为0000 0000 0000 0000 0000 0000 1111 1111
原码即为补码,为255
练习二:
int main()
{
char a = -128;
printf("%u\n", a);
return 0;
}分析:
-128:1000 0000 0000 0000 0000 0000 1000 0000(原)
1111 1111 1111 1111 1111 1111 1000 0000(补)
char a:1000 0000(补)
整形提升:由于char为有符号数,则补1,即为:1111 1111 1111 1111 1111 1111 1000 0000(补)
结果转换为原码,最高位不是符号位
注:整形提升补位应看原数据的类型。正数补0,负数补1,无符号补0 。
整数的大小
以char类型为例:
signed char:-128 ~ 127
unsigned char:0 ~ 255
其它整形的分析同理
int main()
{
int a = -20;
unsigned int b = 10;
printf("%d\n", a + b);
printf("%u\n", a + b);
return 0;
}分析:
a:1000 0000 0000 0000 0000 0000 0001 0100 原
1111 1111 1111 1111 1111 1111 1110 1011 反
1111 1111 1111 1111 1111 1111 1110 1100 补
b:0000 0000 0000 0000 0000 0000 0000 1010 补
a+b:1111 1111 1111 1111 1111 1111 1111 0110 补
%d:1000 0000 0000 0000 0000 0000 0000 1010 (-10)
for(unsigned int i = 9; i >= 0; i--)
{
printf("%u\n", i);
}上述代码死循环,因为无符号整型不可能为负
int main()
{
char arr;
int i;
for (i = 0; i < 1000; i++)
{
arr = -1 - i;
}
printf("%d\n", strlen(arr));return 0;
}由于为有符号字符数组,故当递减到-128后值为127,再进行递减
2、浮点型存储
科学计数法:nEm <=> n10^m
int main()
{
int n = 9;
float pf = (float*)(&n);
printf("%d\n", n);// 1
printf("%f\n", pf);// 2
pf = 9.0f;
printf("%d\n", n);// 3
printf("%f\n", *pf);// 4
return 0;
}分析:
[*]创建整形n并赋值为9,打印整形时也得9
[*]读取n的地址并存放至浮点型指针,由于浮点型与整形的存储方式不同,故解引用后无法得到目的值
[*]解引用pf并赋值为9.0f,由于浮点型与整形的存储方式不同,故无法得到目标整数值
[*]但浮点数的存储正常,可得到浮点数值
详细分析
[*]数据存放
根据国际标准IEEE,任意二进制浮点数V可以表示成如下形式:
(-1)^SM\2^E
(-1)^S表示符号位,S为0为正数,S为1为负数
M表示有效数字,大于等于1,小于2
2^E表示指数位
例如:
十进制:9.0
二进制:1001.0
科学计数:(-1)^0 1.001 2^3
对于32位(float类型)浮点数,最高位存放S,接着8位是指数E,剩余23位为有效数字M
对于64位(double类型)浮点数,最高位存放S,接着11位是指数E,剩余52位为有效数字M
对于有效数字M和指数E有特殊规定:
[*]由于M满足大于等于1且小于2,故可省略小数点前的1,以增加数据精度
[*]E为无符号整数,但实际上E可以为负数,故对存入内存时的真实值必须加上1个中间值(8位为127,11位为1023)
例:
float f = 5.5f;十进制:5.5
二进制:101.1
二进制科学计数:(-1)^0 1.011 2^2
内存存储:0 10000001 01100000000000000000000
内存存储(十六进制):0x40b00000
[*]数据取出
指数E从内存中取出还可分为3种情况:
[*]E不为全0或全1
指数E-127(或1023)得真实值,该值的M需要加1再进行计算
[*]E全为0
该值的真实值为趋于0的值,该值的M也无需加1,可直接计算
[*]E全为1
该值的真实值为趋于正负无穷的值
重新分析例题:
十进制浮点数:9.0
二进制浮点数:1001.0
科学计数:(-1)^0 1.001 2^3
内存存储(浮点型指针):0 10000010 00100000000000000000000
内存存储(整形指针):0100 0001 0001 0000 0000 0000 0000 0000
============================================================
十进制整数:9
原码=补码(整形指针):0000 0000 0000 0000 0000 0000 0000 1001
内存存储(浮点型指针):0 00000000 00000000000000001001
十进制浮点数:趋近于0
文档来源:51CTO技术博客https://blog.51cto.com/u_15285915/3202421
页:
[1]