C语言指针数组与二级指针、数组指针用法详解

Elena
Elena
发布时间:2026-10-15 | 2人浏览过
原创

本文将系统梳理C语言中指针数组、二级指针和数组指针的核心用法。重点介绍指针数组定义多字符串的方法,剖析二级指针的内存寻址逻辑,以及数组指针在操作二维数组时的具体实现,配合代码示例与图示帮助理解。

1. 指针数组的基础定义与应用

指针数组是数组元素均为指针变量的数组,常用于统一存储同类型的数据。在绝大多数实际场景中,它主要用于保存一组字符串。

第1步:定义指针数组格式

目的: 明确语法结构。

规则: 格式为 类型说明符 *数组名[ 元素个数 ]。例如 int *p[10]; 表示定义了一个包含10个整型指针变量的数组。[] 的优先级高于 *,因此先结合成数组,再说明是指针。

第2步:使用指针数组存储字符串

入口: C语言源代码编辑器。

动作: 定义字符指针数组并在初始化列表中赋值。由于字符串常量存储在只读区,这种方式适合读取展示,但不支持修改内容。

代码实例:

#include <stdio.h>
int main()
{
    char *name[5] = {"Hello",
                     "Pig",
                     "Pk",
                     "Welcome",
                     "DJANGo"};
    int i;
    for (i = 0; i < 5; i++)
    {
        printf("%s\n", name[i]);
    }
    return 0;
}

2. 二级指针(指针的指针)原理解析

二级指针本质上是“指针的地址”,即一个指针变量用来保存另一个指针变量的内存地址。它是处理指针数组或动态多维数组的重要基础。

第1步:建立三级关系链

入口: C代码中的变量声明区。

参数说明: a 为普通变量,p 为指向 a 的一级指针,q 为指向 p 的二级指针。

操作: 依次赋值地址并进行解引用。一级指针解引一次得到值,二级指针需解引两次。**

int main()
{
    int a = 100;
    //定义一个一级指针,用于保存变量的地址
    int *p = &a;
    //定义一个二级指针,用于保存一级指针的地址
    int **q = &p;
    
    // *p 获取 a 的值,**q 同样获取 a 的值
    printf("a = %d %d %d\n", a, *p, **q);
    // &a 是a的地址,p 存储了&a,*q 存储了&p(即p的地址),所以打印出 p 的内容也就是 &a
    printf("&a = %p %p %p\n", &a, p, *q);  
    return 0;
}

3. 字符串在内存中的三种存在形式

理解指针离不开对字符串存储区域的认识。以 I LOVE C 为例,常见的三种存储方式及其区别如下:

  1. 字符数组(栈区/静态区):
    char string[100] = "I LOVE C";
    直接在内存中开辟空间存放字符串副本。可读可改,但受限于定义的容量。
  2. 字符串指针(文字常量区):
    char *str = "I LOVE C";
    字符串常量本身存放在不可变的文字常量区,指针 str 仅存储该常量的首地址。注意:str 本身只是存放地址编号,无法通过 str[0] = 'y' 修改内容。
  3. 堆区动态分配:
    通过 malloc 在堆上申请空间,然后使用 strcpy 拷贝数据。这种方式使用最灵活,需要手动管理内存(free),适用于大小不确定的场景。

4. 数组指针的定义与实战

数组指针(Array Pointer)是一个指针变量,它指向的是一个完整的数组。其核心特征是运算跨度:加1时跳过的字节数等于整个数组的大小,常用于操作二维数组。

第1步:掌握数组指针的定义

格式: 指向的数组的类型 (*指针变量名)[ 指向的数组的元素个数 ]。
例如 int (*p)[5]; 表示 p 是一个指针,它指向一个包含5个整数的数组。

重要特性: p + 1 会使指针向下移动一个数组的长度(即跳过5个整型,共20字节),从而指向下一个一维数组的首地址。

第2步:利用数组指针遍历二维数组

目的: 在函数间传递二维数组,且保持语义清晰。

动作: 将二维数组名传给形参为数组指针的函数。由于数组名退化为首元素的地址(对于二维数组而言,首元素是一维数组),二者类型兼容。

// 定义数组指针
void test1()
{
    int a[3][5]; // 定义一个3行5列的数组
    int(*p)[5];  // 定义了一个数组指针变量p,p+1跳一个有5个元素的整型数组
    
    // a 代表第0行的地址,a+1 代表第1行的地址,中间相差 sizeof(a[0]) 即 20 字节
    printf("a=%p\n", a);      
    printf("a+1=%p\n", a + 1); 
    
    p = a;
    printf("p=%p\n", p);
    printf("p+1=%p\n", p + 1);
    return;
}

// 函数传参示例
void func(int (*p)[5], int x, int y)
{
    p[x][y] = 101; // 直接通过数组指针修改数组元素
}

void test2()
{
    int i, j;
    int a[3][5];
    func(a, 0, 1);
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 5; j++)
        {
            printf("%d ", a[i][j]);
        }
        printf("\n");
    }
}

总结

指针数组擅长处理集合数据(如多个字符串),而数组指针则是操作多维数据结构(如矩阵/二维数组)的有力工具。二级指针则打通了指针地址之间的映射链条。区分它们的关键在于阅读时的语法规则优先级以及指针步进时的内存跨度。以上就是C语言指针数组、二级指针及数组指针的详细教程,更多关于C语言指针用法的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表