(一)C语言的数据类型
首先,C语言的数据类型有哪些呢(即内置类型)
整形大家族:(1)char //字符数据类型
(2)short //短整型
(3)int //整形
(4)long //长整型
(5)long long //更长的整形
浮点型大家族:(1)float //单精度浮点数
(2)double //双精度浮点数
构造类型:(1)数组类型
(2)结构体类型 struct
(3)枚举类型 enum
(4)联合类型 union
指针类型:(1)int *pi
(2)char *pc
(3)float* pf
(4)void* pv
空类型:void表示空类型,通常应用于函数的返回类型、函数的参数、指针类型。
例如调用函数的时候无参数时,写成Add(void),在传参时就会报错。
#include <stdio.h>
void Add(void)
{
printf("hello! world");
}
int main()
{
Add();
Add(100);
return 0;
}
(二)整形在内存中的存储
整形在内存中是以补码的形式存放的,对于正整数来说,它的源码,反码,补码相同。对于负整数来说,它的补码等于源码符号位不变,其它位按位取反,然后再末位加一。
例如,int a = -1;在VS2019中查看a的内存如图,一个整形四个字节,一个字节八个比特位,这时候我们看到的存储方式是十六进制的,一个f在二进制下是1111,那么在二进制下,a的补码为11111111111111111111111111111111。
按照按位取反,末位加一的规矩,a的反码为10000000000000000000000000000000,a的源码为10000000000000000000000000000001。
当int a = 0x11223344时,我们再来看内存,可以看到,从44到11,内存以字节为单位进行存放的时候,是从高地址向低地址存放的,像这样把一个数字的低位字节的内容,存放在内存的低地址处,把高位字节的内容存放在内存的高地址处,就是小端字节存储。与小端字节存储正好相反,大端字节存储把一个数字的低位字节的内容,存放在内存的高地址处,把高位字节的内容存放在内存的低地址处。
那么,如何判断是小端字节存储还是大端字节存储呢?我们是这样来实现的。因为char类型的整形含两个字节,int类型的变量含四个字节,定义一个数为1,通过强制类型转换,int转换为char,如果是小端字节存储,在内存中为01 00 00 00,转换后为1,如果是大端字节存储,转换后则为0,通过判断取值来判断大小端字节存储。
include<stdio.h>
int check_sys()
{
int i=1;
return (*(char*)&i);
}
int main()
{
int ret=check_sys();
if(ret==1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
(三)浮点型在内存中的存储
浮点型在fioat.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可以表示成下面的形式:
● (-1)^S*M*2^E
● (-1)^s表示符号位,当s=0, V为正数,当s=1, V为负数。
● M表示有效数字,大于等于1小于2。
● 2^E表示指数位。
例如,一个浮点数数5.5,第一位小数相当于2的-1次方,写成二进制就是101.1,即(-1)^0*1.011*2^2,其中S=0,M=1.011,E=2。,S,M,E在内存中的占比是这样的。
因为规定M是大于1并且小于2的,所以在M中,默认第一位为1,所以只需要存小数点后面的位数就行了。E被解读成一个无符号数,但是实际上E也有可能是负数,对于这样的情况,IEEE 754规定,存入内存时必须加上一个中间数,对8位的E,加127,对11位的E,加1023。
例如,存入5.5,S=0,M=1.011,E=2,得0 10000001 01100000000000000000000,转化为16进制为40 B0 00 00,可以观察到内存中就是此数。
要从内存中取出E时,要分三种情况:
(1)E不全为0或不全为1:即指数E的计算值减去127 (或1023) ,得到真实值,再将有效数字M前加上第一位的1。
(2)E全为0:E等于1-127 (或者1-1023) 即为真实值,
(3)E全为1:这时,如果有效数字M全为0,表示无穷大(正负取决于符号位s) 。
这样就可以很好的解释前面的代码啦,(不足之处,欢迎大家指正)。