C++指针与数组:简单详细指南
1. 指针数组(数组里存指针)
是什么:一个普通数组,但每个元素都是指针
定义:
cpp
类型* 数组名[大小];
例子:
cpp
int a=1, b=2, c=3;
int* numPtr[3] = {&a, &b, &c}; // 存了3个int指针
char* names[2] = {"小明", "小红"}; // 存了2个字符串指针
怎么用:
cpp
cout << *numPtr[0]; // 输出1(通过第一个指针访问a的值)
cout << names[1]; // 输出"小红"(第二个字符串)
特点:
- 数组有多大,就能存多少个指针
- 适合存储多个字符串(字符串本身就是指针)
2. 数组指针(指向数组的指针)
是什么:一个指针,专门指向整个数组
定义:
cpp
类型 (*指针名)[数组大小];
例子:
cpp
int arr[3] = {10,20,30};
int (*arrPtr)[3] = &arr; // 指向这个包含3个数的数组
int matrix[2][3] = {{1,2,3}, {4,5,6}};
int (*rowPtr)[3] = matrix; // 指向第一行(也是一个数组)
怎么用:
cpp
cout << (*arrPtr)[1]; // 输出20(先解引用得到数组,再取下标1)
cout << rowPtr[1][2]; // 输出6(第二行第三列)
特点:
- 对指针加减时,会跳过整个数组
- 处理二维数组时特别有用
3. 指针数组指针(指向指针数组的指针)
是什么:指向"装着指针的数组"的指针
定义:
cpp
类型* (*指针名)[数组大小];
例子:
cpp
int x=1, y=2, z=3;
int* ptrArr[2] = {&x, &y}; // 指针数组
int* (*superPtr)[2] = &ptrArr; // 指向这个指针数组的指针
怎么用:
cpp
cout << *(*superPtr)[0]; // 输出1(先得到数组,再取第一个指针,最后解引用)
特点:
- 用得比较少,主要在需要修改指针数组本身时使用
对比总结
类型 | 例子 | 本质 | 常见用途 |
---|---|---|---|
指针数组 | int* arr[3] |
数组(元素是指针) | 存多个字符串 |
数组指针 | int (*arr)[3] |
指针(指向数组) | 处理二维数组 |
指针数组指针 | int* (*arr)[3] |
指针(指向指针数组) | 动态修改指针数组 |
记忆口诀
-
看括号:有括号先看括号内
int* arr[3]
→ 先看[3]
是数组,再看*
是指针 → 指针数组int (*arr)[3]
→ 先看(*arr)
是指针,再看[3]
→ 数组指针
-
从右向左读:
int* (*arr)[3]
:arr
是...- 指针
*
... - 数组
[3]
... - 指针
int*
...
→ 指向"包含3个int指针的数组"的指针
实际应用场景
场景1:学生姓名管理(指针数组)
cpp
const char* students[3] = {"张三", "李四", "王五"};
for(int i=0; i<3; i++) {
cout << "学生" << i+1 << ": " << students[i] << endl;
}
场景2:处理成绩表(数组指针)
cpp
int scores[2][3] = {{90,85,95}, {70,80,75}};
// 用数组指针处理行
int (*row)[3] = scores;
cout << "第一行平均分: "
<< (row[0][0] + row[0][1] + row[0][2])/3;
场景3:动态指针数组(指针数组指针)
cpp
int* createArray(int size) {
return new int[size];
}
int main() {
int* (*funcPtr)(int) = &createArray; // 指向函数的指针
int* dynamicArr = funcPtr(5); // 创建动态数组
// 使用后记得 delete[] dynamicArr;
}
记住:遇到复杂声明时,先找变量名,然后按照优先级(括号>右边>左边)逐步解析。