跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C

C 语言指针与数组的深度关联及实战应用

深入讲解 C 语言中指针与数组的紧密关系。首先阐述数组名本质为指向首元素的常量指针,以及下标访问与指针算术运算的等价性。接着通过求和、逆序等实战案例展示指针遍历数组的方法。随后区分指针数组与数组指针的定义及用途差异,并指出常见越界访问和定义混淆问题及其解决方案。最后总结核心知识点,强调避免越界的重要性。

涅槃凤凰发布于 2026/3/30更新于 2026/5/2227 浏览
C 语言指针与数组的深度关联及实战应用

C 语言指针与数组的深度关联及实战应用

在这里插入图片描述

💡 学习目标:掌握指针与数组的内在联系,熟练运用指针操作数组元素,解决实际开发中的数组遍历、数据交换等问题;学习重点:数组名的本质、指针算术运算操作数组、指针数组与数组指针的区别及应用。

38.1 数组名与指针的关系

在 C 语言中,数组和指针有着密不可分的联系。很多初学者会混淆数组名和指针变量的概念,其实二者既有关联,又有本质区别。

38.1.1 数组名的本质

💡 数组名在大多数情况下会被编译器隐式转换为指向数组首元素的常量指针。
我们来看一段简单的代码:

#include <stdio.h>
int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    printf("数组首元素地址:%p\n", arr);
    printf("数组首元素地址:%p\n", &arr[0]);
    printf("数组首元素值:%d\n", *arr);
    return 0;
}

运行结果:

数组首元素地址:0x7ffeefbff560 数组首元素地址:0x7ffeefbff560 数组首元素值:10 

从结果可以看出,arr 和 &arr[0] 表示的是同一个地址,都是数组首元素的地址。
使用 *arr 可以直接访问数组的首元素,这就验证了数组名可以被当作指针使用。

⚠️ 注意:数组名是常量指针,不能被修改。
以下代码是错误的:

int arr[5];
arr++;// 错误,数组名是常量,不能进行自增操作
38.1.2 数组下标与指针的等价关系

💡 C 语言规定,数组下标访问 arr[i] 等价于指针访问 *(arr + i)。
这个等价关系是指针操作数组的核心,我们可以通过指针算术运算来访问数组的任意元素。
示例代码:

#include <stdio.h>
int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    int i;
    for(i = 0; i < 5; i++){
        printf("arr[%d] = %d, *(arr + %d) = %d\n", i, arr[i], i, *(arr + i));
    }
    return 0;
}

运行结果:

arr[0] = 10, *(arr + 0) = 10 arr[1] = 20, *(arr + 1) = 20 arr[2] = 30, *(arr + 2) = 30 arr[3] = 40, *(arr + 3) = 40 arr[4] = 50, *(arr + 4) = 50 

可以看到,两种访问方式的结果完全一致。
指针算术运算 arr + i 会根据数组元素的类型自动计算偏移量,int 类型的元素每个占 4 字节,arr + 1 就会偏移 4 字节,指向数组的下一个元素。

38.2 指针操作数组的实战案例

掌握了数组和指针的关系后,我们就可以用指针来实现各种数组操作,让代码更简洁高效。

38.2.1 案例 1:指针遍历数组并求和

🔧 需求:定义一个整型数组,使用指针遍历数组所有元素,计算元素总和。

#include <stdio.h>
int main() {
    int arr[6] = {1, 2, 3, 4, 5, 6};
    int sum = 0;
    int *p = arr;// 指针 p 指向数组首元素
    int len = sizeof(arr)/sizeof(arr[0]);// 计算数组长度
    // 使用指针遍历数组
    for(int i = 0; i < len; i++){
        sum += *p;
        p++;// 指针自增,指向下一个元素
    }
    printf("数组元素总和:%d\n", sum);
    return 0;
}

运行结果:

数组元素总和:21 

💡 技巧:sizeof(arr) / sizeof(arr[0]) 是计算数组长度的通用方法,适用于任意类型的数组。

38.2.2 案例 2:指针实现数组元素逆序存放

🔧 需求:定义一个整型数组,使用指针将数组元素逆序存放,要求不使用额外数组空间。

#include <stdio.h>
void reverseArray(int *arr, int len){
    int *left = arr;// 指向数组首元素
    int *right = arr + len -1;// 指向数组尾元素
    int temp;
    while(left < right){// 交换两个指针指向的元素
        temp = *left;
        *left = *right;
        *right = temp;
        left++;// 左指针右移
        right--;// 右指针左移
    }
}
int main(){
    int arr[5] = {10, 20, 30, 40, 50};
    int len = sizeof(arr)/sizeof(arr[0]);
    int *p = arr;
    printf("原数组:");
    for(int i = 0; i < len; i++){
        printf("%d ", *(p + i));
    }
    printf("\n");
    reverseArray(arr, len);
    printf("逆序数组:");
    for(int i = 0; i < len; i++){
        printf("%d ", *(p + i));
    }
    printf("\n");
    return 0;
}

运行结果:

原数组:10 20 30 40 50 逆序数组:50 40 30 20 10 

⚠️ 注意:函数参数中的数组名会被直接当作指针处理,在函数内部使用 sizeof(arr) 得到的是指针的大小,而不是数组的实际大小。

38.3 指针数组与数组指针的区别

在实际开发中,指针数组和数组指针是两个容易混淆的概念,二者的用途截然不同。

38.3.1 指针数组

💡 指针数组是存放指针的数组,数组的每个元素都是一个指针变量。
定义格式:类型 *数组名 [数组长度];
示例:定义一个指针数组存放 3 个字符串的地址

#include <stdio.h>
int main(){
    char *strArr[3]={"C 语言","指针","数组"};// 指针数组
    for(int i = 0; i < 3; i++){
        printf("%s\n", strArr[i]);
    }
    return 0;
}

运行结果:

C 语言 指针 数组 

指针数组的核心是数组,数组的每个元素都是指针类型,常用于存放多个字符串或者多个一维数组的地址。

38.3.2 数组指针

💡 数组指针是指向整个数组的指针,它指向的是一个数组整体,而不是单个元素。
定义格式:类型 (*指针名)[数组长度];
示例:使用数组指针遍历二维数组

#include <stdio.h>
int main(){
    int arr[2][3]={{1,2,3},{4,5,6}};
    int (*p)[3]= arr;// 数组指针,指向包含 3 个 int 元素的数组
    // 遍历二维数组
    for(int i = 0; i < 2; i++){
        for(int j = 0; j < 3; j++){
            printf("%d ",*(*(p + i)+ j));
        }
        printf("\n");
    }
    return 0;
}

运行结果:

1 2 3 4 5 6 

⚠️ 注意:数组指针的定义中,(*p) 的括号不能省略。
如果省略括号,int *p[3] 就变成了指针数组,二者的含义完全不同。

38.4 常见问题与解决方案

38.4.1 问题 1:指针越界访问数组

❌ 错误代码:

int arr[3]={1,2,3};
int *p = arr;
for(int i = 0; i < 5; i++){
    printf("%d\n",*p++);// 越界访问,会读取到随机值
}

✅ 解决方案:

  1. 严格根据数组长度控制指针的访问范围,避免循环次数超过数组元素个数。
  2. 使用 sizeof 计算数组长度,确保遍历范围准确。
38.4.2 问题 2:混淆指针数组与数组指针

❌ 错误原因:定义时缺少括号,或者对二者的指向对象理解不清。
✅ 解决方案:

  1. 牢记定义格式:指针数组是 类型 *数组名 [],数组指针是 类型 (*指针名)[]。
  2. 指针数组的元素是指针,数组指针指向的是整个数组。

38.5 本章小结

✅ 数组名在大多数情况下会被转换为指向首元素的常量指针,arr[i] 等价于 *(arr + i)。
✅ 可以通过指针算术运算高效操作数组,实现遍历、求和、逆序等功能。
✅ 指针数组是存放指针的数组,数组指针是指向整个数组的指针,二者定义和用途不同。
✅ 操作数组时要避免指针越界,严格控制访问范围。

目录

  1. C 语言指针与数组的深度关联及实战应用
  2. 38.1 数组名与指针的关系
  3. 38.1.1 数组名的本质
  4. 38.1.2 数组下标与指针的等价关系
  5. 38.2 指针操作数组的实战案例
  6. 38.2.1 案例 1:指针遍历数组并求和
  7. 38.2.2 案例 2:指针实现数组元素逆序存放
  8. 38.3 指针数组与数组指针的区别
  9. 38.3.1 指针数组
  10. 38.3.2 数组指针
  11. 38.4 常见问题与解决方案
  12. 38.4.1 问题 1:指针越界访问数组
  13. 38.4.2 问题 2:混淆指针数组与数组指针
  14. 38.5 本章小结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Git 查看提交与删除行数:统计代码贡献量指南
  • C++ 红黑树详解与实现
  • 基于 Trae IDE 与 MCP Server 实现 Figma 设计稿转前端代码
  • OpenClaw 联网工具完全指南:提升 AI 实时信息获取能力
  • MoltBot 集成钉钉 Stream 流式接入配置指南
  • 二分查找算法实战:平方根与山脉数组
  • OpenClaw Web Search 工具配置与渠道详解
  • FPGA加速图像处理:核心算法全解析
  • Python 国内常用镜像源汇总与配置指南
  • 基于单片机的智能家居监控系统设计与实现
  • Vue 状态管理实战:Bus 事件总线的核心用法与注意事项
  • C++ 多态机制详解
  • 大语言模型 (LLM) 产品开发流程参考
  • C++ 哈希表原理及 unordered_set/map 应用
  • Qt QWebChannel 前后端通信原理与示例
  • Fish Speech 1.5 结合 Whisper 实现语音转文本再转语音闭环
  • 希尔排序算法详解:原理、实现与优化
  • llama.cpp 实战指南:在普通电脑上运行大模型
  • RGThree-Comfy:ComfyUI 高效 AI 绘画扩展工具
  • 前端 TypeScript 高级技巧:提升代码安全与质量

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online