1. 操作系统内存管理

①内存分布

②堆和栈的区别

栈区:
1. 栈区用来保存局部变量、函数的形参返回值、及函数调用时的保护现场;
2. 栈区由操作系统自动管理;
3. 栈区默认大小为8M, 比堆区空间小;
4. 栈的访问效率要比堆的访问效率高;
堆区:
1. 堆区由开发人员手动申请和释放,使用完时及时释放,否则造成内存泄露。
2. 堆区空间比栈空间大,访问效率相对较低。

③堆区空间使用场景

在函数中开辟的空间,希望随着函数结束,该空间任然存在,可以去堆上开辟。
当需要的空间比较大时,可以去堆上开辟,栈区空间有限,默认8M
堆区空间使用(动态内存分配):
void *malloc(size_t size);
功能:向堆区申请内存空间
参数:
size:申请的空间字节数
返回值:
成功:返回申请到的空间首地址
失败:NULL
void free(void *ptr);
功能:释放申请的堆区空间
参数:
ptr:申请到的堆区的空间首地址。
void *calloc(size_t nmemb, size_t size);
功能:向堆区申请数组空间,并清空成0
参数:
nmemb:申请的数组的元素个数
size:数组中的每个元素占的字节数
返回值:
成功:返回申请到的空间首地址
失败:NULL
内存泄露:程序运行过程中,堆区申请的空间在使用完没有释放,则造成内存泄露。
避免内存泄露:堆区申请的空间使用完,及时使用free()进行释放。
动态数组:
int *pa = malloc(ARRAY_LEN*sizeof(int));
if (NULL == pa)
{
      printf("malloc error\n");
     return 0;
}
for (int i = 0; i < ARRAY_LEN; ++i)
{
     pa[i] = i;
}
for (int i = 0; i < ARRAY_LEN; ++i)
{
     printf("%d ", pa[i]);
}
printf("\n");

2. 位运算

①位运算基础

&      按位与 全11,有00

|       按位或 有11,全00
^       按位异或 相同为0,相异为1
~      按位取反 1取反为00取反为1
<<    按位左移 按位左移,低位补0 num << n <===> num * 2^n
>>    按位右移 按位右移动,有符号数高位补符号位;无符号数高位补0
num >> n <===> num / 2^n
9 & 6
0000 0000 0000 0000 0000 0000 0000 1001 &
0000 0000 0000 0000 0000 0000 0000 0110
0000 0000 0000 0000 0000 0000 0000 0000
9 | 6
0000 0000 0000 0000 0000 0000 0000 1001  |
0000 0000 0000 0000 0000 0000 0000 0110
0000 0000 0000 0000 0000 0000 0000 1111
9 ^ 6
0000 0000 0000 0000 0000 0000 0000 1001  ^
0000 0000 0000 0000 0000 0000 0000 0110
0000 0000 0000 0000 0000 0000 0000 1111
~9
~0000 0000 0000 0000 0000 0000 0000 1001
1111 1111 1111 1111 1111 1111 1111 0110
9 << 3
0000 0000 0000 0000 0000 0000 0000 1001 << 3
0000 0000 0000 0000 0000 0000 0100 1000
9 >> 3
0000 0000 0000 0000 0000 0000 0000 1001 >> 3
0000 0000 0000 0000 0000 0000 0000 0001

②位运算的使

a.指定n位置1

0000 0000--0000 1000
                      0000 0001 << 3
                      0000 1000
1010 0000 |
0000 1000
1010 1000
num = num | 1 << n;
1010 0001 | 0000 0001 << 6
0100 0000
1110 0001

b. 指定第n位清0

1010 1010 & ~(1 << 3)
1111 0111
1010 0010
1111 0111 <==> ~0000 1000 <==> ~(1 << 3)
num = num & ~1 << n;
0011 1100 1010 1010 & ~(1 << 10) & ~(1 << 11)
1111 1011 1111 1111
0011 1000 1010 1010
1111 0111 1111 1111
0011 0000 1010 1010
0000 0100 0000 0000
1111 1011 1111 1111

c. 两数交换(不使用中间变量)

方法一(位运算,无中间变量):

a = a ^ b;

b = a ^ b;
a = a ^ b;
====
a ^ a == 0
a ^ 0 == a
b = (a ^ b) ^ b = a ^ b ^ b = a ^ (b ^ b) = a ^ 0 = a;
a = a ^ b = a ^ b ^ a = 0 ^ b = b;
方法二(有中间变量):
int tmp = 0;
tmp = a;
a = b;
b = tmp;
方法三(求和方式,无中间变量):
a = a + b;
b = a - b; ===>a + b -b = a
a = a - b; ===>a + b - b = a + b - a
=>位运算符的优先级:
~ 大于 << >> 大于 & 大于 ^ 大于 |
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐