学习 C 语言绕不开指针它也是很多初学者的难点。本篇结合实操代码、内存原理、易错点从零带你吃透基础指针、指针运算、数组与指针联动适合新手系统复习与收藏。一、什么是指针 指针变量1. 基础概念内存中每一块空间都有地址就像房间门牌号。指针本质就是内存地址。指针变量专门用来存放地址的变量。定义格式数据类型 * 变量名int a 10; int* p; // 定义int类型指针变量p p a; // 取地址符取出变量a的地址存入指针p2. 两个核心操作符取地址符取出变量首字节地址变量名得到地址。*解引用操作符根据指针中存储的地址找到对应内存空间操作该空间的值。示例演示#includestdio.h int main() { int c 5; int* p c; printf(%d\n, *p); // 通过地址取值输出 5 *p 3; // 通过地址修改值 printf(%d\n, c); // 原变量被修改输出 3 return 0; }简单理解指针相当于变量的 **“第二入口”**可以绕过变量名直接读写内存。二、指针变量的大小指针存储的是内存地址指针占用字节数只由编译环境决定和指针类型无关。32 位环境 (x86)地址占 32 位 → 所有指针统一占4 字节64 位环境 (x64)地址占 64 位 → 所有指针统一占8 字节验证代码#includestdio.h int main() { printf(%zu\n, sizeof(char*)); printf(%zu\n, sizeof(int*)); printf(%zu\n, sizeof(double*)); return 0; }三、指针类型的真正作用既然指针大小和类型无关那前面的char*、int*有什么意义指针类型决定两件事解引用权限、指针 ± 整数时的偏移步长。1. 解引用决定一次能操作几个字节int*解引用一次访问4 字节char*解引用一次访问1 字节示例#includestdio.h int main() { int a 0x11223344; char* p a; *p 0; // 仅修改低1个字节 return 0; }调试可见只有 1 字节数据被修改这就是类型带来的访问权限差异。2. 指针 ± 整数决定地址偏移步长指针1不是地址单纯 1而是向后偏移一个「指向类型」的大小int* 1地址向后偏移 4 字节char* 1地址向后偏移 1 字节四、特殊指针void* 空指针void*是通用空指针特点可以接收任意类型变量的地址常用于泛型场景不能直接解引用也不能做±整数运算原因void无具体类型编译器不知道它一次该访问几个字节。五、四大类指针运算核心重点结合生活例子类比方便记忆日期 天数 日期 | 日期 日期无意义 指针运算遵循相同逻辑指针 整数 指针地址向后偏移指针 - 整数 指针地址向前偏移指针 - 指针 整数仅同一块连续内存有效计算元素个数指针 指针语法允许但逻辑无意义禁止使用1. 指针 ± 整数遍历数组最常用数组是连续内存空间配合指针遍历是 C 语言经典写法。写法 1指针不动下标移动#includestdio.h int main() { int arr[10] {1,2,3,4,5,6,7,8,9,10}; int sz sizeof(arr) / sizeof(arr[0]); int* p arr; // 数组名arr等价于 arr[0] for (int i 0; i sz; i) { printf(%d , *(p i)); } return 0; }写法 2指针自身移动p#includestdio.h int main() { int arr[10] {1,2,3,4,5,6,7,8,9,10}; int sz sizeof(arr) / sizeof(arr[0]); int* p arr; for (int i 0; i sz; i) { printf(%d , *p); p; } return 0; }写法 3while 循环 地址比较无额外循环变量利用指针可以比较大小的特性终止条件p 数组末尾下一个地址#includestdio.h int main() { int arr[10] {1,2,3,4,5,6,7,8,9,10}; int sz sizeof(arr) / sizeof(arr[0]); int* p arr; while (p arr sz) { printf(%d , *p); p; } return 0; }易错提醒arr[10] 是越界元素取值遍历判断必须用 arr[10]取地址。2. 指针 - 指针模拟实现 strlen 求字符串长度规则两个指针必须指向同一块连续内存差值 中间元素个数。自定义字符串长度函数#includestdio.h int my_strlen(const char* a) { const char* p a; // 字符串以 \0 作为结束标志 while (*p ! \0) { p; } // 结束指针 - 起始指针 字符个数 return (int)(p - a); } int main() { char s[] abc; printf(%d, my_strlen(s)); return 0; }补充C 环境建议参数加 const匹配字符串常量 const char* 类型避免编译警告。六、高频易错点汇总1.char s abc; 错误2.char 只能存单个字符单引号 a字符串必须用 char[] 或 char*双引号 abc。正确写法char s[] abc; / char* s abc;3.int* p arr[0]; 错误arr[0] 是数组元素值指针需要存地址正确int* p arr[0]; / int* p arr;4.数组下标越界int arr[10] 合法下标 0~9arr[10] 是非法内存严禁取值、解引用。5.64 位环境指针相减警告64 位下指针差值为 64 位整型返回int会提示丢失数据可加强制转换 (int)(p-a)。七、学习总结指针 内存地址指针变量 存放地址的变量核心操作 取地址、* 解引用指针大小由编译环境决定类型决定访问字节数和偏移步长指针四大运算±整数 遍历数组、-指针 求元素个数、指针可比较大小数组名本质是数组首元素地址数组和指针可以灵活混用牢记边界问题数组下标、字符串结束符 \0、内存越界是指针 bug 重灾区。