一、前言数组和指针是 C 语言核心重难点二者联系紧密、用法互通。本文从基础语法、关系、常用写法、易错点、实战案例逐一梳理适合入门复习、笔记归档。二、数组基础2.1 一维数组定义与初始化1. 定义格式数据类型 数组名[元素个数];示例intarr[5];// 定义包含5个int元素的数组未初始化值为随机垃圾值2. 初始化方式// 1. 全部初始化intarr1[5]{1,2,3,4,5};// 2. 部分初始化未赋值元素自动补0intarr2[5]{1,2};// 3. 省略数组长度长度由初始化元素个数决定intarr3[]{1,2,3};// 4. 字符数组字符串charstr1[6]{a,b,c,d,e,\0};charstr2[]abcde;// 自动末尾补 \0 结束符2.2 数组访问与下标1. 数组下标从 0 开始下标范围0 ~ 元素个数-12. 访问格式数组名[下标]3. 严禁数组下标越界C 语言不做下标检查越界会篡改内存、程序崩溃。示例intarr[3]{10,20,30};printf(%d,arr[0]);// 输出 102.3 数组名的含义重点1. 普通场景数组名代表数组首元素的地址常量指针值不可修改。2. 特殊场景仅有两种sizeof(数组名)计算整个数组占用的总字节数数组名取出整个数组的地址区分示例intarr[5]{1,2,3,4,5};printf(%p\n,arr);// 首元素地址printf(%p\n,arr[0]);// 与 arr 地址完全一致printf(%p\n,arr);// 整个数组的地址数值和上面相同但类型不同3.计算数组元素个数公式通用intlensizeof(arr)/sizeof(arr[0]);三、指针基础3.1 指针概念指针本质是存放内存地址的变量。1. 普通变量存放数据值2. 指针变量存放另一个变量的内存编号地址3.2 指针定义、取地址、解引用1定义格式 数据类型 * 指针变量名;*仅表示该变量是指针不参与类型运算。2核心运算符取地址符取出变量的内存地址*解引用符根据地址找到对应内存中的数据基础示例inta10;int*pa;// p 存放变量 a 的地址printf(%p\n,a);// a 的地址printf(%p\n,p);// 和 a 完全一致printf(%d\n,*p);// 解引用取出地址对应的值10*p20;// 通过指针修改 a 的值printf(%d\n,a);// 输出 203.3 空指针与野指针1空指针 NULLNULL 本质是地址 0代表指针不指向任何有效内存用途指针初始化、判断指针是否有效2野指针高危错误指针指向随机、未知、不受管控的内存产生原因指针未初始化、指针指向的变量已销毁、越界访问后果程序崩溃、数据异常、内存篡改解决指针定义即初始化为 NULL不使用后再次置空。3.4 指针加减运算核心指针加减不是单纯加减数字而是按指向类型的字节跨度移动。规则指针 n向后移动 n 个「指向类型」的长度指针 - n向前移动 n 个「指向类型」的长度示例inta10;int*pa;p;// int占4字节p 地址 4四、指针与数组的深度关系重中之重4.1 数组下标等价写法数组访问 arr[i] 与指针写法 完全等价公式arr[i]*(arri)推导1arr 是首元素地址2arr i地址向后偏移 i 个元素3*(arri)解引用取出对应元素反向写法也成立i[arr] *(i arr)语法合法不推荐使用。完整示例intarr[3]{10,20,30};inti0;printf(%d ,arr[i]);printf(%d ,*(arri));// 两行代码输出结果一致4.2 指针遍历数组最常用写法方式 1数组名 下标常规方式 2指针变量遍历工程常用#includestdio.hintmain(){intarr[5]{1,2,3,4,5};int*parr;// p 指向数组首元素intlensizeof(arr)/sizeof(arr[0]);for(inti0;ilen;i){printf(%d ,*(pi));}return0;}精简遍历写法int*parr;while(*p!\0)// 字符数组/字符串专用{printf(%c,*p);p;}4.3 字符数组、字符串与字符指针1 字符数组可修改内容charstr[]hello;str[0]H;// 合法数组内存可改写2区分总结char str[]栈内存可读可写char *str指向只读字符串常量只能读、不能改4.4 二级指针简单了解一级指针指向普通变量二级指针指向一级指针变量定义与使用inta10;int*pa;// 一级指针int**ppp;// 二级指针printf(%d,**pp);// 输出 10五、一维数组做函数参数高频使用数组作为函数参数时会退化为指针函数内部无法用 sizeof 计算数组总大小。错误写法函数内求长度失效voidtest(intarr[]){intlensizeof(arr)/sizeof(arr[0]);// 结果错误arr已是指针}标准规范写法数组传参必须额外传递数组长度#includestdio.hvoidprintArr(int*arr,intlen){for(inti0;ilen;i){printf(%d ,arr[i]);}}intmain(){intarr[5]{1,2,3,4,5};intlensizeof(arr)/sizeof(arr[0]);printArr(arr,len);// 数组名传参等价传首元素地址return0;}函数形参两种等价写法// 两种写法完全一致本质都是指针voidfunc(intarr[]);voidfunc(int*arr);六、经典易错点总结1 数组名是常量指针不能被赋值intarr[5];arrNULL;// 错误数组名地址不可修改2下标越界C 语言不检查下标运行直接异常。3字符串结束符 \0字符数组手动赋值必须手动加 \0否则乱码双引号字符串自动补充 \04指针未初始化 / 空指针解引用程序直接崩溃。5数组传参退化指针函数内不能用 sizeof 求数组长度。6字符串常量指针不可写char *str “abc” 不能修改内容。7arr 和 arr 的区别地址数值相同类型不同arr1 会跳过整个数组。七、常用代码模板模板 1计算数组元素个数intarr[]{1,2,3,4,5};intlengthsizeof(arr)/sizeof(arr[0]);模板 2指针遍历整型数组int*parr;for(inti0;ilength;i){printf(%d ,*(p));}模板 3指针遍历字符串charstr[]C language;char*pstr;while(*p){printf(%c,*p);p;}模板 4数组作为函数参数标准格式voiddealData(int*buf,intn){// 功能代码}八、学习总结1数组是连续内存空间靠下标访问指针是存放地址的变量。2数组名默认代表首元素地址因此数组和指针语法高度互通。3arr[i] 等价 *(arri)是二者互通的核心公式。4数组传参退化为指针务必手动传递长度。5野指针、空指针、数组越界、字符串修改是四大高频 BUG。6指针和数组是后续结构体、动态内存、数据结构的基础必须熟练掌握。