首页 > 编程笔记

C++数组指针(指向数组的指针)详解

数组指针就是指向数组的指针。

数组是同类型数据的集合,集合中的元素按照顺序在内存中连续排列。用指针指向数组其实就是让指针指向这段连续内存的首地址,也就是数组中第一个元素(下标为 0)的地址。

借助数组指针,程序员可以通过内存地址直接访问和操作数组,为内存管理提供了更高的灵活性和效率。

数组指针的定义

定义一个指向数组的指针变量与定义普通指针没有什么不同,即定义一个跟数组元素类型相同的指针即可,语法如下:
类型标识符 *指针名;
例如,在下面的代码中就分别定义了两个指针,并指向同一个数组:
int num[10];  // 定义一个整形数组

int *p;       // 定义一个与数组元素类型相同的指针
p = &num[0];  // 令指针指向数组的首个元素

int *q = &num[0]; // 初始化指针,令其指向数组的首个元素
除此之外,也可以直接将数组名赋值给指针。在大多数情况下,数组名代表的就是数组的首地址。

因此,定义一个数组指针可以使用如下的代码:
int num[10];  // 定义一个整形数组

int *p;       // 定义一个与数组元素类型相同的指针
p = num;  // 令指针指向一个数组

int *q = num; // 初始化指针,令其指向一个数组

数组指针的使用

数组是一段连续的内存,而指针又可以通过加减整数进行移动,因此可以通过数组指针访问数组中的元素。

用指针访问数组,和用下标访问数组的效果是一样的。

例如,一个指向数组 arr 的指针 p,访问第 i+1 个元素(下标为 i),可以用 *(p+i),也可以用 arr[i],这两种方法是等价的。由于数组名代表的是数组的首地址,所以也可以用*(arr+i)来访问第 i+1 个元素。
#include <iostream>

int main() {
    int arr[5] = { 1,2,3,4,5 };

    int* p = arr;

    std::cout << "*(p+2)=" << *(p + 2) << std::endl;
    std::cout << "arr[2]=" << arr[2] << std::endl;
    std::cout << "*(arr+2)=" << *(arr + 2) << std::endl;
    return 0;
}
运行结果为:

*(p+2)=3
arr[2]=3
*(arr+2)=3

注意,使用指针访问数组时不要越界,即确保移动后的指针仍指向的是数组中的某个元素,超出数组的范围将导致程序异常甚至崩溃。

在如下的 C++ 程序中,借助数组指针实现数组元素的反转。
#include <iostream>

int main() {
    int array[5] = { 1, 2, 3, 4, 5 };
    int *arrayPtr = array; // 初始化数组指针

    std::cout << "原始数组: ";
    for (int i = 0; i < 5; i++) {
        std::cout << array[i] << " ";
    }
    std::cout << std::endl;

    int* p = array; // 指向数组第一个元素的指针
    int* q = p + (sizeof(array) / sizeof(int)) - 1; //指向数组最后一个元素的指针
   
    //两个指针相遇则终止循环
    while (p < q) {
        //交换两个指针指向的元素
        int t = *p;
        *p = *q;
        *q = t;

        p++; // p 指针向后移动
        q--; // q 指针向前移动
    }

    std::cout << "反转后的数组: ";
    for (int i = 0; i < 5; i++) {
        std::cout << array[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}
运行结果为:

原始数组: 1 2 3 4 5
反转后的数组: 5 4 3 2 1

在上面的程序中,分别对两个指针施行自加和自减操作,从而实现指针的移动。并且前指针往后移,后指针往前移,两个指针指向的数据正好是需要交换的两个元素。

推荐阅读