C++ 指针详解
在 C++ 中,指针(Pointer) 是变量的内存地址,指针可以指向变量、数组、字符串、函数等,是 C++ 强大且灵活 的特性之一。本文将全面解析 C++ 指针,包括 定义、操作、指针运算、指针数组、指向函数的指针、指针与 new/delete 的结合 等内容。
1. 指针的基本概念
1.1 什么是指针?
指针是 存储变量地址 的变量,它的值是 内存地址,而不是数据本身。
int a = 10; // 普通变量
int* p = &a; // p 存储 a 的地址
&(取地址运算符): 获取变量的内存地址。
*(解引用运算符): 访问指针指向的变量值。
2. 指针的定义与使用
2.1 定义指针
数据类型* 指针变量名;
示例:
int a = 10;
int* p = &a; // p 指向 a
注意:
int *p;和int* p;都可以,*绑定p,表示它是指针。
2.2 访问指针指向的值
#include <iostream>
using namespace std;
int main() {
int a = 10;
int* p = &a;
cout << "变量 a 的值: " << *p << endl; // 解引用
return 0;
}
输出:
变量 a 的值: 10
3. 指针运算
指针支持加法、减法等运算,常见有:
- 指针 + n(p + n):指针向后移动
n个单位(按数据类型大小)。 - 指针 – n(p – n):指针向前移动
n个单位。 - 指针相减(p2 – p1):计算两个指针间的元素个数。
int arr[] = {10, 20, 30};
int* p = arr; // p 指向 arr[0]
cout << *(p + 1) << endl; // 20
cout << *(p + 2) << endl; // 30
注意:指针移动时,步长 依赖数据类型(
sizeof(type))。
4. 指针与数组
4.1 指针遍历数组
int arr[] = {1, 2, 3, 4, 5};
int* p = arr; // 指针指向数组首元素
for (int i = 0; i < 5; i++) {
cout << *(p + i) << " ";
}
输出:
1 2 3 4 5
数组名本质上是指针常量,即
arr == &arr[0]。
4.2 指针运算在数组中的应用
int arr[] = {10, 20, 30};
int* p = arr;
cout << p[0] << endl; // 等价于 *(p + 0)
cout << p[1] << endl; // 等价于 *(p + 1)
5. 指针与字符串
5.1 指针指向字符串
char str[] = "Hello";
char* p = str; // 指针指向字符串
cout << p << endl; // Hello
5.2 字符串指针 vs. 字符数组
char str1[] = "Hello"; // 字符数组
char* str2 = "Hello"; // 指针(存储字符串的地址)
str1允许修改,但str2不能修改,因为它指向的是 字符串常量。
6. 指针数组
指针数组 是一个数组,每个元素都是指针。
const char* strs[] = {"C++", "Java", "Python"};
cout << strs[0] << endl; // C++
cout << strs[1] << endl; // Java
cout << strs[2] << endl; // Python
strs[i]是 指针,指向字符串的首地址。
7. 指针的指针(多级指针)
二级指针 存储的是 一级指针的地址:
int a = 10;
int* p = &a; // 一级指针
int** pp = &p; // 二级指针
访问二级指针的值
cout << **pp; // 10
**pp先解引用pp得到p,再解引用p得到a。
8. 指针与 new / delete(动态内存管理)
8.1 动态分配单个变量
int* p = new int(42); // 申请一个 int
cout << *p; // 42
delete p; // 释放内存
8.2 动态数组
int* arr = new int[5]; // 申请数组
for (int i = 0; i < 5; i++) {
arr[i] = i * 2;
}
delete[] arr; // 释放数组
delete释放单个变量,delete[]释放数组。
9. 函数指针
函数指针用于 指向函数,可用于 回调函数。
#include <iostream>
using namespace std;
void sayHello() {
cout << "Hello, world!" << endl;
}
// 定义函数指针
void (*funcPtr)();
int main() {
funcPtr = sayHello; // 赋值
funcPtr(); // 调用函数
}
函数指针传参
void execute(void (*func)()) {
func();
}
execute(sayHello); // 传入函数指针
10. nullptr vs. NULL
在 C++11 及以上,建议使用 nullptr 代替 NULL:
int* p = nullptr;
nullptr是 强类型指针空值,比NULL更安全。
11. 总结
- 指针存储变量的地址,可用于数组、字符串、动态内存等。
*解引用,&取地址。- 指针运算支持
+-,移动时单位为 类型大小。 - 数组名是指针,
arr == &arr[0]。 - 多级指针:
int** p存储int*。 - 动态内存 需要
new申请,delete释放。 - 函数指针:可用于 回调函数。
更多详细内容请关注其他相关文章!