我们学习了这么久的C语言已经知道,我们平时常用的C语言类型是整型和浮点型,那它们在内存中是如何存储的你了解吗?本篇介绍整型在内存中的存储方式,浮点数在内存中的存储方式放在下篇。
目录
1.数据类型
1.1数据类型介绍
无外乎:
char
short int int long int long long int
float double
类型的意义:使用这个类型开辟内存空间的大小,大小决定了使用范围。
1.2类型基本归类
1.整形类型:char short int int long int long long int
2.浮点数类型:float double
3.构造类型,(自定义类型)
4.结构体类型:struct
5.枚举类型:enum
6.联合类型:union
7.指针类型:int *p; char *pc; float *pf; void *pv;
8.空类型:void,通常应用于函数的返回类型、函数的参数、指针类型。
2.整型在内存中的存储
2.1整型在内存中的存储
1.一个变量的创建是要在内存中开辟空间的,空间的大小是根据不同类型决定的;
2.整型在内存中存储的是二进制补码,打印的是原码;
例如20:
正数的原码、反码、补码都相同
原码:00000000 00000000 00000000 00010100
反码:00000000 00000000 00000000 00010100
补码:00000000 00000000 00000000 00010100
-10
原码:10000000 00000000 00000000 00001010
反码:11111111 11111111 11111111 11110101
补码:11111111 11111111 11111111 11110110
在计算机系统中,数值一律用补码来表示和存储,原因在于使用补码可以将符号位和数值域统一处理,同时加法和减法也可以统一处理(CPU只有加法器);此外,补码和原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
2.2大端与小端的介绍
定义
1.大端(存储模式):指数据的低位保存在高地址中,而数据的高位字节序存储保存在内存的低地址中;
2.小端(存储模式):数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。
我们通俗点来说,大端就是低放高,高放低;小端就是低放低,高放高。
我们接下来通过代码来确定一下自己的计算机的存储模式。
int main()
{
int a = 1;
char* p = (char*)&a;//转变为只能查看一个字节的类型
if (1 == *p) //是01 00 00 00还是00 00 00 01,其中01是低位
{
printf("是小端存储\n");
}
else
printf("是大端存储\n");
return 0;
}
大家可以在自己的计算机上试一下,通过调试查看内存,深刻体会一下。
2.3截断和整形提升
什么是截断,顾名思义就是把它断开,那么整型提升也就是把一个函数类型提升为整型。
我们通过例子来学习。
int main()
{
char a = -1;
signed char b = -1;
unsigned char c = -1;
printf("a=%d\nb=%d\nc=%d\n", a, b, c);
return 0;
}
我们发现,a和b输出的都是-1,而c却变成了255,为什么会这样呢?让我们来分析一下:
1.我们首先要明白,不管signed还是unsigned,a、b、c都是char类型的,最大只有8个bit;
2.%d打印的是有符号的整数,也就是int型;
3.char a=-1;(char是字符型)
其中-1是整数,有32个bit
原码:10000000 0000000 0000000 00000001
反码:11111111 11111111 11111111 11111110
补码:11111111 11111111 11111111 11111111
因为char类型只能存8个bit,所以把-1放入a中就发生了截断,也就是:11111111
又因为要以%d的形式输出,是32个bit,所以此时又要对它进行整形提升。
a是个有符号数,有符号数整型提升按原来的符号位提升,也就是在它的左端补齐足够符号位。提升之后的结果就是:11111111 11111111 11111111 11111111,这是补码,换回原码就是:10000000 0000000 0000000 00000001,所以输出还是-1;
4. signed char b = -1;它与char a原理相同,大家可以自己尝试一下;
5. unsigned char c = -1;我们直接从它被截断开始说起:
11111111这是截断后的,然后我们进行整形提升,因为它是无符号数:无符号数进行整型提升时高位补0;也就是:00000000 00000000 00000000 11111111这是补码,因为是正数,所以原码与补码相同,也是00000000 00000000 00000000 11111111,所以是255;
6.不要以为看起来结果相同就觉得它没有进行运算,其实它内里进行了复杂的变化。
我们再来看一个例子:
int main()
{
char a = -128;
printf("a=%u\n", a);
return 0;
}
分析一下:
1.首先%u打印的是无符号整数,还是32个bit;
2.-128
原码:10000000 00000000 00000000 10000000
补码:11111111 11111111 11111111 10000000
然后发生截断,就是10000000,按a的类型进行整型提升,就是:
11111111 11111111 11111111 10000000,因为%u打印的是无符号整数,所以原码和补码所表示的数是一样的,所以打印出来的就是4294967168。
不要觉得大小端存储、截断和整型提升与整型数据存储没有关系,学会了这些,才能更好的了解数据在内存中的存储。好了,这部分内容还需要大家自行体会,加油!!!