1.数据类型
(1)整形类型有
char 向内存申请1个字节空间,反映char能访问的权限是一个字节,char分为 unsigned char和signed char两种类型在无特殊声明的情况下默认是那种类型取决于编译器(VS是signed char),由于char类型在内存中是以ASSIC码值的形式进行存储,所以被归为整形
short 向内存申请2个字节空间,反映short能访问的权限是2个字节,short分为 unsigned short和signed short两种类型在无特殊声明的情况下默认是signed short。
int 向内存申请4个字节空间,反映sint能访问的权限是4个字节,int分为 unsigned int和signed int两种类型在无特殊声明的情况下默认是signed int。
long向内存申请4/8个字节空间,反映long能访问的权限是2个字节,long分为 unsigned long和signed long两种类型在无特殊声明的情况下默认是signed long。
long long向内存申请8个字节空间,反映long long能访问的权限是2个字节,long long分为 unsigned long long和signed long long两种类型在无特殊声明的情况下默认是signed long long。
(2)浮点类型
float向内存申请4个字节空间,反映浮点数的不同精度
double向内存申请8个字节空间,反映浮点数的不同精度
(3)构造类型
struct结构体
enum枚举类型
数组‘
union联合类型
(4)指针类型
int* p;
void*p;
(5)空类型
void通常用于函数的返回类型、函数的参数、指针类型。
2.整形的存储
整形在存储中主要是以补码形式进行存储
整形在二进制中有三种表现形式分别是原码,反码,补码,由原码到补码是符号位不变将其他位进行按位取反,然后加一得到补码。
补码相对于其他形式的具有的优势就是补码在计算是将符号位和加减法进行统一,此外,转成补码的进程对于补码转成原码的过程是相同的,避免了进程的占用。
补码在计算机中存储的时候是对补码进行存储,具体是如何存储,存储形式有两种(1)大端存储字节模式(2)小端存储字节模式两种存储方式取决于你的电脑硬件,大端存储字节模式就是将二进制进行高位存储在低地址,低位存储在高地址,在地址中高地址就是地址值大,低地址就是地址值小 ,所以我们就可以知道大端存储字节模式就是将字节存储正向。小端存储字节模式就是将高位存储在高地址,将低位存储在低地址,形成将字节存储反向。
下面写一种如何去判断大端存储和小端存储的代码
#include<stdio.h>
int main()
{
int a = 9;
int b = *(char*)&a;
if (b == 0)
printf("大端");
else
printf("小端");
return 0;
}
对于unsigned修饰的数据类型是是将其无符号,表现是数据是二进制代码没有符号位(在整形提升是补的是0),全都是数值位,他们都是大于等于0的;signed是第一个是符号位,其他是数值位。对于不同的数据类型中有符号的char根据计算时存储的值范围是-128~127从00000001-01111111(127)-10000000(-128)-11111111(-1)的值进行变化,如果超出数值范围就会指取补码的后面八位,进行截断。
对于无符号的char进行数据范围0-255,如果超出范围根据展现的不同视角转换(是否要如何进行补码转换)如果超出数值范围就会指取补码的后面八位,进行截断。
对于其他数据类型的design和unsigned基本可以和上面进行类推。
下面介绍一些例子
由于-1不在0-255范围中,-1的补码是11111111在unsigned char看来11111111全都是数值位,所以值是255
上面%u是以无符号整形的方式进行打印,以无符号整形的角度来看先整形提升为11111111111111111111111111111111,然后再看成无符号全是数值位,得到的结果就是4294967295。
3.浮点数的存储
浮点数在内存中有两种数据类型float和double分别是32个比特和64个比特
浮点数在内存中是以(-1)^S*M*2^E的形式进行转换得到S,M,E的值,将S存储在首位,对于float将后面八位存储E+127转换为二进制后的值,让后去掉M首位的1后面小数点后转换成二进制再存储进后面23位(注意:有一些小数转换成二进制后太长因此造成float的精度是有限的,小数点后转换成的二进制位数注意每位的权重)double是将E+1023转换成二进制存储在后面11位,让后去掉M首位的1后面小数点后转换成二进制再存储进后面52位中。
对于(-1)^S*M*2^E,例如float a=1.5在存储时将其转换成(-1)^0*1.1*2^0其存储是0111111101000000000000000000000
要注意的是E在存储时无符号整数为了防止出现-1不在范围中所以我们就要E+127(或者E+1022)
在我们取出浮点数时是先第一位是1则是负,0则是正,对于E的部分如果不是全1或者全0我们就按照同样的方法转换成(-1)^S*M*2^E的形式然后转换成十进制就得到结果了,例如二进制是 01000010110000000000000000000000由于不是全1或者全0所以转换成(-1)^S*M*2^E的形式, 为(-1)^0*1.10000000000000000000000*2^10000101然后转换为十进制6.5;
如果我们发现E的部分全是0,就说明这个值特别小,我们就要将转换时就将M不补1,还原成0.M的形式
如果E的部分全为1说明小数是一个特别大的数字。
注意:只要大于一个字节的存储都有大小端,因此float和souble在存储时都有大小端