一、指针基础概念1. 地址与指针内存以字节为最小单位每个字节拥有唯一编号这个编号就是内存地址。指针 内存地址地址就是指针指针指向一块内存空间。指针变量专门用来存储内存地址的变量自身会占用内存空间。2. 指针变量定义语法基类型 *变量名;基类型决定指针指向空间存储的数据类型决定解引用时读取多少字节*类型标记代表该变量是指针int *pint; // 指向int类型的指针 char *pch; // 指向char类型的指针 float *pf; // 指向float类型的指针 int *pi, *pj; // 同时定义两个int指针指针占用空间64 位系统所有指针统一占8 字节32 位系统所有指针统一占4 字节printf(指针大小%lu\n, sizeof(int*));3. 指针初始化与赋值int num 100; // 合法初始化 int *p NULL; // 空指针推荐默认初始化方式 int *p2 num; // 存储变量num的地址 p num; // 运行时赋值野指针高危问题定义未初始化、指向已释放内存、非法地址的指针。 危害解引用野指针会造成程序崩溃、内存错乱。 规避方案指针定义时默认赋值NULL仅赋值合法变量 / 数组的地址4. 两个核心运算符1 取地址运算符作用获取变量首字节内存地址 规则只能作用于变量不能对常量、表达式取地址int a 10; printf(a的地址%p\n, a);2* 解引用指针运算符作用通过指针存储的地址访问对应内存的数据p保存的地址值*p地址对应内存里的数据类型等于指针基类型int num 20; int *p num; *p 666; // 修改num的值 printf(num %d\n, num); // 输出666内存读取字节规则char*解引用读取 1 字节int*解引用读取 4 字节double*解引用读取 8 字节5. 指针算术运算仅、--、整数、-整数、指针-指针有意义* / %无任何使用价值指针 n向后偏移n * sizeof(基类型)字节指针 - n向前偏移n * sizeof(基类型)字节指针1 - 指针2计算两个指针之间相隔的元素个数int arr[5] {1,2,3,4,5}; int *p arr; p; // 向后偏移4字节指向arr[1]二、指针作为函数参数地址传递核心作用在被调函数中修改主调函数的变量值传递做不到函数需要返回多个结果时通过指针参数带出多组数据传递数组 / 大块数据避免完整拷贝节省内存开销示例交换两个数字值传递失败地址传递成功#include stdio.h // 值传递无法交换主函数变量 void swap_err(int a, int b) { int tmp a; a b; b tmp; } // 地址传递通过指针修改外部变量 void swap(int *pa, int *pb) { int tmp *pa; *pa *pb; *pb tmp; } int main(void) { int x 10, y 20; swap_err(x, y); printf(错误交换x%d y%d\n, x, y); swap(x, y); printf(正确交换x%d y%d\n, x, y); return 0; }三、指针与一维整形数组1. 数组名本质数组名arr等价于arr[0]是首元素地址常量右值不能赋值修改 寻址等价公式plaintextarr[i] ↔ *(arr i) arr[i] ↔ arr i2. 一维数组两种传参写法完全等价// 写法1数组形式 void print_arr(int a[], int len); // 写法2指针形式底层完全一致 void print_arr(int *pa, int len);完整遍历示例#include stdio.h void print_arr(int *pa, int len) { for(int i 0; i len; i) { printf(%d , *(pa i)); } } int main(void) { int arr[5] {11,22,33,44,55}; int len sizeof(arr)/sizeof(arr[0]); print_arr(arr, len); return 0; }四、拓展区分指针数组 vs 数组指针1. 指针数组char *str[]数组里每一个元素都是字符指针存储多个字符串的地址内存不连续。char *name[] {张三, 李四, 王五};2. 数组指针char str[][16]二维字符数组整块连续内存每行存放一个完整字符串函数传参必须指定列数。char name[3][16] {张三, 李四, 王五};高频面试坑二者不可互相作为函数参数传递内存布局完全不同。五、万能指针 void*void*可以接收任意类型变量、数组的地址使用前必须强制转换为对应类型指针才能解引用int num 100; void *p num; // 解引用需要强制转换 printf(%d\n, *(int*)p);未完结待更新