C++ 指针与数组:深度掌握两者关系
C++ 指针与数组
本教程通过实例详解指针与数组的内在联系,包括指针算术、数组名退化、多维数组指针等核心知识点。
C++ 指针不仅能存储单个变量地址,也能存储数组元素地址。例如:
int *ptr;
int arr[5];
ptr = arr; // 将数组首元素地址赋给指针
此处 ptr = arr; 等价于 ptr = &arr[0];。数组名 arr 在大多数上下文中会退化为指向首元素的指针。
其余元素地址分别为 &arr[1]、&arr[2]、&arr[3]、&arr[4]。
指向任意数组元素
若 ptr 指向首元素,则 ptr + 3 指向第 4 个元素:
int *ptr;
int arr[5];
ptr = arr;
ptr + 1 等价于 &arr[1];
ptr + 2 等价于 &arr[2];
ptr + 3 等价于 &arr[3];
ptr + 4 等价于 &arr[4];
同样可通过解引用访问元素:
*ptr == arr[0];
*(ptr + 1) == arr[1];
*(ptr + 2) == arr[2];
*(ptr + 3) == arr[3];
*(ptr + 4) == arr[4];
若初始化 ptr = &arr[2];,则:
ptr - 2 == &arr[0];
ptr - 1 == &arr[1];
ptr + 1 == &arr[3];
ptr + 2 == &arr[4];

注意: ptr 与 ptr + 1 地址差为 4 字节,因 int 在 64 位系统占 4 字节。若指针指向 char,则差值为 1 字节。
示例 1:指针与数组地址对比
// 显示数组各元素地址:数组下标 vs 指针算术
#include <iostream>
using namespace std;
int main() {
float arr[3];
float *ptr;
cout << "Displaying address using arrays:" << endl;
for (int i = 0; i < 3; ++i) {
cout << "&arr[" << i << "] = " << &arr[i] << endl;
}
ptr = arr; // ptr = &arr[0]
cout << "\nDisplaying address using pointers:" << endl;
for (int i = 0; i < 3; ++i) {
cout << "ptr + " << i << " = " << ptr + i << endl;
}
return 0;
}
输出
Displaying address using arrays: &arr[0] = 0x61fef0 &arr[1] = 0x61fef4 &arr[2] = 0x61fef8 Displaying address using pointers: ptr + 0 = 0x61fef0 ptr + 1 = 0x61fef4 ptr + 2 = 0x61fef8
程序先用下标打印地址,再用指针算术打印,结果完全一致。
在大多数上下文中,数组名会退化为指针。这正是我们能用指针访问数组元素的原因。但指针与数组并不相同——数组名不是可修改的左值,且 sizeof(arr) 返回整个数组大小而非指针大小。
数组名不退化为指针的情况请参考:When does array name not decay into a pointer?
示例 2:直接用数组名作为指针
// 使用指针记法输入/输出数组元素
#include <iostream>
using namespace std;
int main() {
float arr[5];
cout << "Enter 5 numbers: ";
for (int i = 0; i < 5; ++i) {
cin >> *(arr + i); // 等价于 cin >> arr[i];
}
cout << "Displaying data:" << endl;
for (int i = 0; i < 5; ++i) {
cout << *(arr + i) << endl; // 等价于 cout << arr[i];
}
return 0;
}
输出
Enter 5 numbers: 2.5 3.5 4.5 5 2 Displaying data: 2.5 3.5 4.5 5 2
此处未单独声明指针变量,直接用数组名 arr 进行指针运算。数组名指向首元素,可视为常量指针(不可修改指向)。
C语言