C++指针
int a = 10; int* p = &a;
变量a 地址:0x1000 存放数据:10
变量p 地址:0x2000 存放数据:0x1000
&a→0x1000p→0x1000(p 中存的值是 a 的地址)*p→10&p→0x2000(指针变量自身的地址)
指针是一个内存变量,存储另一个内存地址
int*:指针类型,代表这个指针指向 int 类型数据
&a:取地址运算符,获取变量 a 的内存地址
*p:解引用运算符,通过地址访问内存上的值
多级指针
int** 二级指针
int* 存放 int 变量地址;
int** 存放 int* 指针变量的地址。
void Alloc(int** pp)
{
*pp = new int(666);
}
//调用
int* p = nullptr;
Alloc(&p);
Const指针
//1. const int* p; 等价 int const *p // 指向【常量数据】:不能 *p=100;指针p本身可以指向别的地址 const int* p; //2. int * const p; //【常量指针】:p的地址不能修改;*p可以修改内容 int * const p = &a; //3. const int * const p; // 双重锁定:指针不能改,指向内容也不能修改 const int * const p;
指针VS数组
int arr[5] = {1,2,3,4,5};
int* p = arr;
数组名隐式转换为首元素指针
数组名是常量指针,不能自增:arr++ 编译报错;p++合法;
sizeof(arr):得到整个数组字节大小; sizeof(p):只得到指针本身大小(8 字节 64 位)
指针与字符串
//方式1:字符串常量(只读内存区) char* str1 = "hello"; // str1[0] = 'x'; 未定义行为,崩溃! //方式2:栈字符数组 char str2[] = "hello"; str2[0] = 'x'; //合法,可以修改
指针和引用
int a = 10; int* p = &a; int& r = a;
引用必须初始化;指针可以初始化为 nullptr;
引用绑定后无法更换指向;指针可以随时指向其他变量;
引用是变量别名,没有独立内存地址;指针自身占用内存;
不存在多级引用;存在多级指针;
使用语法:引用直接用,指针需要*解引用
动态内存&指针new/delete
int* p = new int(100); delete p; p = nullptr; //释放后置空,防止野指针 //数组形式 int* arr = new int[10]; delete[] arr; arr = nullptr;
风险
- 内存泄漏:堆内存 new 后丢失指针,没有 delete
- 双重释放:同一指针多次 delete
函数指针:用于存放函数地址的指针,用于回调动态调用
int Add(int a,int b){return a+b;}
//定义函数指针:接收两个int,返回int
int (*fp)(int,int) = Add;
//调用
int res = fp(1,2);
总结
- 指针 = 存储内存地址的变量
- 空指针 (nullptr)、野指针、悬垂指针风险
- 指针运算步长由类型决定;void * 不能自增、不能直接解引用
- 多级指针
**:用于函数内修改外部指针 - const 三种指针区分;指针和引用核心差异
- 数组名 ≠ 指针,数组名是常量指针
- new/delete 管理堆裸指针;现代 C++ 优先智能指针
- 函数指针保存函数地址,实现回调
浙公网安备 33010602011771号