整数在内存中的存储
在操作符的时候,我们就已经知道了,整数的二进制的表示方法有三种,就是原码,反码和补码,而整数的存储是在内存中存储它的补码,其中,对于有符号的整数,三种表⽰⽅法均有符号位和数值位两部分,符号位都是⽤0表⽰“正”,⽤1表⽰“负”,最⾼位的⼀位是被当做符号位,剩余的都是数值位。
正整数的原、反、补码都相同。负整数的三种表⽰⽅法各不相同。
对于负数而言,原码,反码,补码的转换:原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。补码:反码+1就得到补码。
大小端字节序和字节序的判断
我们调试如下的代码,得到结果
那么什么是大小端呢?
实超过⼀个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分为⼤端字节序存储和⼩端字节序存储,下⾯是具体的概念:
⼤端(存储)模式:
是指数据的低位字节内容保存在内存的⾼地址处,⽽数据的⾼位字节内容,保存在内存的低地址处。⼩端(存储)模式:
是指数据的低位字节内容保存在内存的低地址处,⽽数据的⾼位字节内容,保存在内存的⾼地址处。
很好,现在我们一起来练习几道和大小端有关的习题吧
练习一
设计一个程序判断当前机器的字节序
int check_sys()
{
int i = 1;
return (*(char *)&i);
}
实际上,我们只需要放入1,然后看返回的第一个字节是1还是0就可以了
练习二
int main()
{
char a= -1;
signed char b=-1;
unsigned char c=-1;
printf("a=%d,b=%d,c=%d",a,b,c);
return 0;
}
这个输出的结果是什么?
a是-1,
//10000000000000000000000000000001
//11111111111111111111111111111110
//11111111111111111111111111111111
取出的是
//11111111
b是-1
//10000000000000000000000000000001
//11111111111111111111111111111111
//11111111
但是c要把最前面的1视作数字位
255
练习三
int main()
{
char a = -128;
printf("%u\n",a);
return 0;
}
a为-128
//10000000000000000000000010000000
//11111111111111111111111101111111
//11111111111111111111111110000000 补码
//10000000
这里认为a是无符号数
char所以要进行整型提升
//11111111111111111111111110000000
int main()
{
char a = 128;
printf("%u\n",a);
return 0;
}
//00000000000000000000000010000000
//10000000
整型提升
//11111111111111111111111110000000
练习四
int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
}
输出结果是什么?
char类型占据1个字节,它放入的内容是:
-1 -2 -3 -4 ... -127 -128 127 126 ... 4 3 2 1 0 -1 -2 ...
当为0是,相当于'\0',所以结果是255
练习五
//X86环境 ⼩端字节序
int main()
{
int a[4] = { 1, 2, 3, 4 };
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
printf("%x,%x", ptr1[-1], *ptr2);
return 0;
}
取a的地址,+1在转换为int*的类型,指向4后面的位置
ptr1[-1]相当于*(ptr1 - 1),也就是4
将单独的a取出来实际是地址,现在视为一个数字,然后+1,就是地址真实+1,整数+1就是+1
然后我们输出红框的内容
浮点数在内存中的存储
常⻅的浮点数:3.14159、1E10等,浮点数家族包括:float,double,long double
浮点数表⽰的范围:float.h中定义
现在给出我们一个代码,请分析他的结果
int main()
{
int n = 9;
float *pFloat = (float *)&n;
printf("n的值为:%d\n",n);
printf("*pFloat的值为:%f\n",*pFloat);
*pFloat = 9.0;
printf("num的值为:%d\n",n);
printf("*pFloat的值为:%f\n",*pFloat);
return 0;
}
输出的结果
我们发现,和我们想的并不同,因此我们知道了,整数和浮点数的存储是不同的
那么,浮点数在内存的存储是什么样的呢?
据国际标准IEEE(电⽓和电⼦⼯程协会)754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:
⽐如,2^10的E是 10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。
E全为0时候, 这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第⼀位的1,⽽是还 原为0.xxxxxx的⼩数。这样做是为了表⽰±0,以及接近于0的很⼩的数字。
E全为1时候,这时,如果有效数字M全为0,表⽰±⽆穷⼤(正负取决于符号位s);
感谢您的观看