在 C++ 中,指针(Pointer)是一个变量,它存储的是另一个变量的内存地址,而不是变量本身的值。指针可以让你直接操作内存地址,这使得 C++ 在进行低级编程时非常强大。指针用于许多用途,例如动态内存管理、数组处理、函数回调等。
基本概念:
-
指针的声明: 声明指针变量时,使用
*来表示该变量是指向某个类型的指针。int* ptr; // ptr 是一个指向 int 类型的指针 -
取地址符
&:&是取地址符,用于获取变量的内存地址。int x = 10; int* ptr = &x; // ptr 存储 x 的地址 -
解引用符
*:*用于解引用,即访问指针所指向的内存地址处的值。int x = 10; int* ptr = &x; // ptr 存储 x 的地址 std::cout << *ptr; // 输出 10,*ptr 解引用,得到 x 的值
指针的基本用法:
1. 指针声明与初始化
int num = 5; // 普通变量
int* ptr = # // ptr 是指向 num 的指针
std::cout << "num: " << num << std::endl; // 输出 5
std::cout << "ptr: " << ptr << std::endl; // 输出 num 的内存地址
std::cout << "*ptr: " << *ptr << std::endl; // 输出 5,*ptr 解引用得到 num 的值
2. 指针与数组
数组名本身是一个指针,指向数组的第一个元素。你可以使用指针遍历数组。
int arr[] = {1, 2, 3, 4, 5};
int* ptr = arr; // ptr 指向数组的第一个元素
for (int i = 0; i < 5; ++i) {
std::cout << *(ptr + i) << " "; // 使用指针遍历数组
}
// 输出: 1 2 3 4 5
3. 指针和动态内存管理
C++ 允许通过 new 和 delete 来动态分配和释放内存,这对处理运行时数据至关重要。
int* ptr = new int(10); // 动态分配内存,存储一个 int 值 10
std::cout << *ptr << std::endl; // 输出 10
delete ptr; // 释放内存
4. 指针数组与数组指针
-
指针数组:是一个数组,数组的每个元素都是指针。
int* ptrArr[3]; // 一个包含 3 个指针的数组 int x = 5, y = 10, z = 15; ptrArr[0] = &x; ptrArr[1] = &y; ptrArr[2] = &z; std::cout << *ptrArr[0] << " " << *ptrArr[1] << " " << *ptrArr[2] << std::endl; // 输出: 5 10 15 -
数组指针:是一个指向整个数组的指针。
int arr[3] = {1, 2, 3}; int (*ptr)[3] = &arr; // ptr 是一个指向数组的指针 std::cout << (*ptr)[1] << std::endl; // 输出 2
5. 指针与函数
指针可以传递给函数,允许函数修改外部变量的值。你还可以使用指针来实现回调函数。
void increment(int* ptr) {
(*ptr)++; // 解引用指针,增加值
}
int main() {
int num = 5;
increment(&num); // 传递变量的地址
std::cout << num << std::endl; // 输出 6
return 0;
}
指针的注意事项:
-
空指针: 指针如果没有指向任何有效地址,它会被初始化为
nullptr(C++11 引入),表示空指针。避免访问空指针,以免引发崩溃。int* ptr = nullptr; // 空指针 if (ptr) { // 如果 ptr 不为空,则可以解引用 } -
野指针: 如果指针指向一个已经释放或不再有效的内存地址,它称为“野指针”。使用野指针会导致未定义行为,因此需要特别小心。
-
指针与内存泄漏: 动态分配的内存如果没有被正确释放,会导致内存泄漏。通过
delete或delete[]来释放内存。 -
指针算术: 在 C++ 中,指针支持算术操作。比如,可以通过加法和减法来访问数组中的元素(指针向前或向后移动)。
int arr[] = {1, 2, 3, 4}; int* ptr = arr; std::cout << *(ptr + 2); // 输出 3,指针加 2 相当于访问 arr[2]
总结:
- 指针 是一个变量,它存储了另一个变量的内存地址。
- C++ 中的指针支持 指针运算、动态内存管理、数组操作 等。
- 使用指针时需要注意 空指针、野指针、内存泄漏 等问题。