文章目录
内存管理
内存区域划分
1>内核空间
用户代码不能读写
2>栈(向下增长) stack
储存局部变量
int * ptr; //指针变量
int num[]; //数组名
char a; //变量名
由编译器自己分配和释放,局部变量,函数参数等储存在该区域。
3>内存映射段
文件映射,动态库,匿名映射。
4>堆(向上增长) heap
需要用户自己手动分配和释放(new,malloc,delete,free)。
5>数据段
静态数据,全局数据。
6>文字常量区(只读常量)
不同的名称的指针可能指向同一块地址(指针的内容相同,编译器自动优化(常量字符串不会被优化))。也可以说文字常量区在代码段。
7>代码段
存放程序的二进制代码。
char *p1; //全局未初始化区,shuju
int a = 0;//全局初始化区,数据段
void main()
{
static int C = 0;//全局(静态)初始化区
char s[] = "abc";//栈
char *p2;//栈
char *p3 = "123456";//123456\0在字符常量区,p3在栈上
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);//分配字节的区域在堆区
char str1[] = "hello.";
char str2[] = "hello.";
char *str3 = "hello.";
char *str4 = "hello.";
free(p1);
free(p2);
system("pause");
}
注意
C/C++中把常量字符串储存到单独的一个内存区域(文字常量区)中,当几个指针指向同一个字符串时,编译器会自动优化,所以会指向同一块内存区域。
但用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。
堆和栈的区别
内置类型数据的储存
1>整型家族
字符 | 对应数据类型 | 所占内存 |
---|---|---|
char | 字符数据类型 | 1字节 |
short | 短整型 | 2字节 32767(2^16-1) |
int | 整型 | 4字节 |
long | 长整型 | 4(32位操作系统)/8(64位操作系统)字节 |
long lnog | 更长的整型 | 8 字节 |
(1)整型在内存中的储存
对于整型来说数据存放内存中其实存放的是补码。
负数的反码原码:
码型 | 概念 |
---|---|
原码 | 直接将二进制按照正负数的形式翻译成二进制就可以。 |
反码 | 将原码的符号位不变,其他位依次按位取反就可以得到了。(符号位0正,1负) |
补码 | 反码+1就可以得到补码。 |
正数的原码,反码,补码都相同。
(2)原因:
"1"使用补码可以将符号位和数值位统一处理。
"2"加法和减法也可以统一处理。
"3"补码与原码的相互转换过程是相同的不需要额外的硬件电路。
(3)大端模式(大端储存,网络字节序)
数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中。
(4)小端模式(小端储存)
数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。
(5)大小端储存小结
"1"这两种储存方式没有优缺点.
"2"寄存器宽度大于一个字节,就存在了如何将多个字节安排的问题.
"3"最好的输入输出流,程序一致用同一种方式.
(6)判断当前机器是大端储存还是小端储存
"1"类型强转:访问变量的地址,如果首地址的元素的是1,则表示是小端,否则就是大端。
void check_sys()
{
int num = 1;
char *p =(char *)#//我们只看前一个字节,所以将&num强转为char*
if(*p == 1)
{
printf("小端");
}
else
{
printf("大端");
}
}
"2"利用联合体的特性:所有成员共用一个空间.
void check_sys()
{
union UN
{
int i;
char j;
}un;
un. i = 1;//如果是小端储存un.c也会被修改
if(un.j==1)
{
printf("小端");
}
else
{
printf("大端");
}
}
2>浮点数家族
字符 | 类型名称 | 所占空间大小 |
---|---|---|
float | 单精度浮点型 | 4字节 |
double | 双精度浮点型 | 8字节 |
(1)浮点型在内存中的储存规则
"1" V=(-1)^S*M*2^E //
"2" (-1)^S表示符号位,当s=0,V为正数;当s=1,V为负数。
"3"M表示有效数字,大于等于1,小于2。
"4"2^E表示指数位。
"5"对于32位的浮点数,最高位是符号位S,接着是8位的指数E,剩下的23位为有效数字M。对于64位的浮点数,最高位1位是S,接着是11位的指数位E,剩下的52位为有效数字M。
十进制-5.0,写成2进制是-101.0,相当于1.01×2^2,按照之前的格式,S=1,M=1.01,E=2。