c语言内存的管理
如何表示这个地址
指针类型
- 想要描述一个指针需要让编译器解决两问题
- 这个指针所占空间的大小(由编译器决定)
- 这个指针指向空间的操作⾏为,即解决 p + 1和 p + 2,C语⾔编译器如何翻译
- 函数指针
int (*arr)(const char * pp, ... ) = printf;//printf这个标签就是代表了一个地址,一个这个函数的地址;
arr("hello world\n");
printf("%p\n", &printf);
printf("%p\n", printf);
函数名是一个指向函数体的常量指针;函数体是一个空间只要是空间就会有首地址;(同数组一样)
指针类型的运算
- ● 获取地址和内容 :
- 获取变量空间的地址:&
- 获取指针指向的数据:*
- 指针的算术运算:指针的加、减运算p + 1,p - 1 指针的偏移加获取数据:[n]
数组是什么
2.1. 数组不是数据类型 为了表示多个同类型的连续空间,构造了⼀个数组结构语法糖 数组名的含义:
- 实际是⼀个常量指针,仍然具备指针的运算能⼒
- 具有特殊的sizeof效果 (数组在定义时,是一个数组,传递一次后就是一个指针了)
- 数组名的取地址是⾮法的,但被编译器给重定义了 数组⽆法约束越界的问题,这也是C被诟病最多的地⽅
数组不是数据类型
普通数组和字符数组的区别
内存的分段管理
段错误:你访问了不该访问的段; 每写一个变量,想一想这个变量放在了哪一个段里面;这个段里面的属性是什么;
一个经典错误
内存分段管理模型和权限
内存各段空间分配和使用
- 指针占用字节大小与电脑的操作系统和编译环境的位数有关,通常是8个字节
- 地址访问空间 * 指针名;
static只会执行一次;
所以说static进行初始化的话,他不会被再次执行;
- //如何判断是否真的学会了指针;
int *p = &a;
void aaa(int *p){ int b = 0; p = &b; }
P->a? P->b?
其实p还是指向a的因为这里p = &b;是在一个新的栈(aaa栈)修改p这个变量里面的值,并没有通过指针修改这里面的值,想要真正的去修改里面的值,那么需要传入int* p;然后再去修改p的值;