C++指针知识点详解
编程小白的指针入门指南 – 用大白话解释复杂概念
📚 知识点目录
基础知识
- 什么是指针?
- 内存地址概念
- 指针的声明
- 指针的初始化
指针操作
- 取址运算符(&)
- 解引用运算符(*)
- 指针的赋值
- 指针的算术运算
高级应用
- 指针与数组
- 指针与函数
- 动态内存分配
- 指针与字符串
特殊指针
- 空指针(nullptr)
- void指针
- 指向指针的指针
- 函数指针
📍 什么是指针?
指针就像是变量的”家庭地址”。想象一下,变量是房子,里面住着数据,而指针就是写有这个房子地址的小纸条。
通俗理解: 指针就是保存其他变量内存地址的变量。它不直接存储数据,而是存储数据的位置。
0x7ffee
42
变量num
➡️
0x7ffa2
0x7ffee
指针ptr
上图中,变量num
存储了值42,指针ptr
存储了num
的地址(0x7ffee)。
📝 指针的声明与初始化
声明指针需要指定指针指向的数据类型,并在变量名前加*
号。
int num = 10; // 一个普通的整型变量
int* ptr; // 声明一个整型指针
ptr = # // 将ptr指向num的地址
// 也可以在声明时直接初始化
int* ptr2 = #
// 访问指针指向的值
cout << *ptr; // 输出10 (解引用)
int* ptr; // 声明一个整型指针
ptr = # // 将ptr指向num的地址
// 也可以在声明时直接初始化
int* ptr2 = #
// 访问指针指向的值
cout << *ptr; // 输出10 (解引用)
注意: 未初始化的指针称为”野指针”,指向随机的内存地址,使用它可能导致程序崩溃。总是初始化指针!
🔧 指针的基本操作
指针有两个核心操作符:&
(取地址)和*
(解引用)。
int num = 42;
int* ptr = # // & 获取num的地址
cout << ptr; // 输出: 0x7ffee (num的地址)
cout << *ptr; // 输出: 42 (*访问该地址的值)
// 通过指针修改变量值
*ptr = 100;
cout << num; // 输出: 100
int* ptr = # // & 获取num的地址
cout << ptr; // 输出: 0x7ffee (num的地址)
cout << *ptr; // 输出: 42 (*访问该地址的值)
// 通过指针修改变量值
*ptr = 100;
cout << num; // 输出: 100
指针也可以进行算术运算,但要注意:指针的加减是根据指向类型的大小进行的。
int arr[3] = {10, 20, 30};
int* ptr = arr; // 指向数组第一个元素
cout << *ptr; // 输出10
ptr++; // 移动到下一个元素 (地址增加4字节,因为int占4字节)
cout << *ptr; // 输出20
int* ptr = arr; // 指向数组第一个元素
cout << *ptr; // 输出10
ptr++; // 移动到下一个元素 (地址增加4字节,因为int占4字节)
cout << *ptr; // 输出20
🧩 指针与数组
数组名实际上就是一个指向数组第一个元素的指针。数组和指针在C++中可以互换使用。
int arr[5] = {1, 2, 3, 4, 5};
// 通过指针访问数组元素
int* ptr = arr; // 等同于 int* ptr = &arr[0];
for(int i = 0; i < 5; i++) {
cout << *(ptr + i) << " "; // 输出数组元素
}
// 数组名也可以像指针一样使用
cout << *(arr + 2); // 输出3
// 通过指针访问数组元素
int* ptr = arr; // 等同于 int* ptr = &arr[0];
for(int i = 0; i < 5; i++) {
cout << *(ptr + i) << " "; // 输出数组元素
}
// 数组名也可以像指针一样使用
cout << *(arr + 2); // 输出3
重要区别: 数组名是常量指针,不能被重新赋值,而普通指针可以指向不同的地址。
⚙️ 动态内存分配
使用new
和delete
操作符可以在程序运行时动态分配内存。
// 动态分配单个整数
int* ptr = new int;
*ptr = 42;
delete ptr; // 使用完后释放内存
// 动态分配数组
int* arr = new int[10];
for(int i = 0; i < 10; i++) {
arr[i] = i * i;
}
delete[] arr; // 释放数组内存
int* ptr = new int;
*ptr = 42;
delete ptr; // 使用完后释放内存
// 动态分配数组
int* arr = new int[10];
for(int i = 0; i < 10; i++) {
arr[i] = i * i;
}
delete[] arr; // 释放数组内存
内存泄漏警告: 动态分配的内存必须手动释放,否则会造成内存泄漏。使用delete
(单个对象)和delete[]
(数组)释放内存。
🚦 特殊指针类型
空指针(nullptr)
表示指针不指向任何有效的内存地址。C++11引入nullptr
关键字代替NULL。
int* ptr = nullptr; // 安全的空指针
if(ptr == nullptr) {
// 指针为空时的处理
}
if(ptr == nullptr) {
// 指针为空时的处理
}
void指针
可以指向任意类型的数据,但在使用前必须转换为具体类型。
int num = 10;
void* vptr = #
// 使用前需要强制类型转换
int* iptr = (int*)vptr;
cout << *iptr; // 输出10
void* vptr = #
// 使用前需要强制类型转换
int* iptr = (int*)vptr;
cout << *iptr; // 输出10
指向指针的指针
指针也可以指向另一个指针,形成多级指针。
int num = 5;
int* ptr = #
int** pptr = &ptr; // 指向指针的指针
cout << **pptr; // 输出5 (两次解引用)
int* ptr = #
int** pptr = &ptr; // 指向指针的指针
cout << **pptr; // 输出5 (两次解引用)