今天我主要给大家带来的是整形数据在内存中的存储和浮点数据在内存中的存储。在我们常用的数据类型包括int型,char型,double型,short型,float型。在这些数据类型中我们可以分为整形家族和浮点家族
1.整形家族
整形家族主要包括
2.大小端
大端存储是指数据的低位放在高地址存储,数据的高位放在低地址存储。
小端存储是指数据的低位放在低地址存储,数据的高位放在高地址存储。
例如在我的电脑中打开vs,写一个变量a=0x11223344,在这里低位是44,高位是11,我们进入调试
它在内存中为44 33 22 11,故我们可以画图为
因此我们可以看到我的电脑为小端存储。对于如何判断电脑的存储方式我们可以写一个判断的小程序,代码如下:
#include <stdio.h> int main() { int a = 1; char* p = (char*)&a; if (*p == 1) printf("小端存储"); else printf("大端存储"); return 0; }
在电脑中,数据是以 二进制的方式进行存储, int类型占4个字节在64位机器中占32个bite位它的二进制位00000000000000000000000000000001。 char类型占1个字节,8个bite位。我们利用指针再将其 强制转化为char*类型,由于我们指向离低地址近的位置,如果是大端存储则为00000000,小端存储则指向00000001.故我们运行程序可以得到是哪一种存储方式。
3.%d和%u
%d打印的是10进制,有符号的类型;
%u打印的是10进制,无符号的类型;
4.练习
4.1练习一
代码如下
#include <stdio.h> 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; }
我们知道整形的数据在内存中以二进制的形式存在,也就是数据的补码,要想知道数据补码,需要得到它的源码和反码。对于-1,它的原码是10000000000000000000000000000001,反码为11111111111111111111111111111110,
补码为11111111111111111111111111111111。由于char占1个字节也就是8个bite位故a,b,c在内存中都是11111111的形式存储。由于需要以%d的形式输出所以需要进行整型提升,a的类型为char,符号位为1所以补1,补码为11111111111111111111111111111111,反码为10000000000000000000000000000000;原码为10000000000000000000000000000001故为-1。b的类型为signed char属于有符号的char需要以%d的形式输出所以需要进行整型提升,符号位为1所以补1,补码为11111111111111111111111111111111,反码为10000000000000000000000000000000;原码为10000000000000000000000000000001故为-1。c的类型为unsigned char 类型属于无符号类型补码原码反码相同,在进行整型提升时补0,补码原码反码为00000000000000000000000011111111.输出255.
4.2 练习二
代码如下
#include <stdio.h> int main() { char a = -128; printf("%u", a); return 0; }
-128的补码为11111111111111111111111110000000由于时char类型所以10000000在内存中存储,由于需要以%u输出,所以需要进行整型提升, 符号位为1所以补1.,得到补码为11111111111111111111111110000000,由于需要以%u输出,所以它是无符号类型,所以原码反码补码相同都是11111111111111111111111110000000,故答案为4294967168。
5.大轮盘理解
对于char由于它是只有8个bite位所有最大为11111111.它的具体数值我们可以画图来了解
我们可以进一步得到:
在signed char类型中
进一步得到
在int short long 类型和这相似,想要研究的小伙伴可以自行计算。
6.浮点家族
7.IEEE标准
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位。
IEEE 754规定:
对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。
对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M
例如10进制的5.5转化为二进制为101.1=(-1)^0*1.011*2^2;
S=0 M=1.011 E=2;
E为一个无符号整数(unsigned int)
这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,我们
知道,科学计数法中的E是可以出
现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127.
所以存储时S=0 E=10000001 M =01100000000000000000000
故在内存中以0 10000001 01100000000000000000000
8.练习
学到这里我们看一下代码
#include <stdio.h> int main() { int a = 9; float* p = (float*)&a; printf("%d\n",a); printf("%f\n", *p); *p = 9.0; printf("%d\n", a); printf("%f\n", *p); return 0; }
在printf("%d\n",a);中毫无疑问是9,对于*p由于在存储时是二进制为00000000000000000000000000001001,由于是浮点型 S=0 E=00000000 M=00000000000000000001001 E=0-127=-127,故(-1)^S * M * 2^E为0;
10进制为9.0二进制为1001.0=(-1)^0*1.001*2^3;
S=0 M=1.001 E=3+127=130;故为0 1000 0010 00100000000000000000000;
printf("%f\n", *p);为9.000000;
到这里我们今天的内容就结束了,内容制作不易,希望大家可以一键三连。