C语言指针核心总结延伸版

发布时间:2026/10/8 9:03:17
C语言指针核心总结延伸版 C语言指针详细总结一、指针基础概念1. 指针是什么指针 地址是内存单元的编号。内存按字节编址每一个字节都有唯一地址编号指针就保存这个编号。2. 指针类型指针本身是独立的数据类型专门用来存放地址。普通int类型处理整数数据指针类型处理内存地址数据。3. 指针变量定义语法基类型 *指针变量名;基类型代表这个指针指向的内存空间里存储的数据类型决定解引用时取多大内存。int a 10; int *p a; // p是int*指针变量存放变量a的内存地址 char *p2 (char *)a; // 强制转换把a的地址交给char类型指针保存32位系统所有指针占4字节64位系统所有指针占8字节。指针变量大小和基类型无关。4.取地址运算符、*解引用间接访问运算符变量取出变量在内存中的起始地址*指针解引用间接访问指针指向的内存取出指针变量里面存储的地址值根据基类型从该地址向后偏移sizeof(基类型)大小的内存把这块内存当成基类型变量读写。int a 10; int *p a; *p 20; // 通过指针间接修改a的值此时a变成20和*互为逆运算(*p) p。5. 两种访问变量方式直接访问直接用变量名a间接访问指针解引用*p核心价值被调函数可以修改主调函数里面的变量数据。二、指针 一维数组数组内存三大特点连续性、单一性元素类型相同、有序性。数组名在参与运算时等价于数组首元素地址。int a[10] {1,2,3,4}; int *p a; //等价 int *p a[0];1. 指针算术运算假设p是int*p N地址向后偏移N * sizeof(int)字节指向往后第N个元素p - N地址向前偏移N * sizeof(int)字节p、p--指针向前/后移动一个元素p - q只有同类型指针才可以相减结果代表两个指针之间相差多少个元素不是字节数。2. 指针关系运算 !直接比较地址编号大小。3. 下标与指针完全等价a[i] *(ai) p[i] *(pi)数组下标本质就是语法糖底层就是指针运算。4. 数组函数形参两种写法完全等价// 接收数组本质接收的是首元素地址形参实际是指针 void printArray(int a[],int len); void printArray(int *a,int len);练习场景用指针实现求数组最大值、数组逆序、排序、二分查找。三、指针 字符一维数组字符串字符串本质末尾带\0的char一维数组。两种表示字符串写法重点区分内存区域//写法1栈内存可读可写 char s[] hello; //写法2指针变量存字符串常量区地址常量区内存只读不能修改内容 char *s hello; const char *s hello; //推荐写法显式标记只读如果执行s[0]H对于char *shello;会崩溃因为修改字符串常量区。const修饰指针就近原则离谁近修饰谁const char *p; //等价 char const *p; // *p只读不能通过指针修改指向的内容p本身可以改变指向别的地方 char * const p; // p本身只读指针变量p不能改指向但是*p可以修改内容 const char * const p; // p不能改指向*p也不能修改内容全部只读函数只做读字符串操作形参建议写const char *提高安全性、兼容性。标准库puts(const char *s)就是典型。常用字符串库函数手写实现重点头文件string.hchar *strcpy(char *dest, const char *src)把src字符串拷贝到dest包含末尾\0返回dest起始地址支持链式调用。char *strncpy(char *dest, const char *src, size_t n)拷贝最多n个字节如果n内没有遇到\0dest不会自动补\0强制拷贝满n次。char *strcat(char *dest, const char *src)先找到dest末尾\0把src拼接过来带上\0返回dest。char *strncat(char *dest, const char *src, size_t n)拼接src最多n个字符无论如何末尾自动追加\0。int strcmp(const char *s1, const char *s2)逐个字符对比遇到不同或\0停止返回两字符差值。int strncmp(const char *s1, const char *s2, size_t n)只对比前n个字符。万能指针void *void*可以接收任意类型地址常用作函数形参不能直接解引用void *必须强制转换成具体指针类型才可以访问内存。示例memcpy(void *dest, const void *src, size_t n)拷贝n个字节原始内存不区分类型。int a[10]{1,2,3,4,5}; int b[10]; memcpy(b,a,sizeof(a)); //整块数组拷贝四、指针 二维数组二维数组本质数组的数组。int a[3][4];代表包含3个元素每个元素是大小为4的int一维数组。1. 数组指针指向一整行的指针int a[3][4]; int (*p)[4] a; // p是数组指针基类型是 int[4]指向二维数组一整行 // 注意区分 int *p[4]; 这个是指针数组p1跳过一整行4个int大小内存二维数组访问等价写法a[i][j] *(*(pi)j)步骤pi定位第i行*(pi)得到该行一维数组名该行首元素地址j定位第j列再解引用取值。2.char型二维数组存储多组字符串//开辟5个字符串空间每个字符串最多9个有效字符\0全部在栈上 char s[5][10] {hello,world,english,china,america}; char (*p)[10] s; //数组指针指向char[10]数组3. 指针数组 二级指针//指针数组数组里面每一个元素都是 char* 字符串指针数组存地址 char *s[5] {hello1,hello2,hello3,hello4}; //二级指针 char**存放一级指针变量的地址 char **p s;char *s[5]数组元素是指针char **p二级指针保存一级指针的地址。使用场景多个字符串排序、找最大字符串、逆序。五、指针函数应用核心被调修改主调80%指针用途函数带出多个返回结果。规则想要修改主调里面哪个变量就把它的地址传给被调函数被调函数内部必须做解引用*运算才可以修改外面变量。示例函数不使用return带出计算结果//求ab结果通过指针参数ret带出 void add(int a,int b,int *ret){ *ret a b; } int main(){ int res; add(3,5,res); //传变量res的地址 // res此时得到8 return 0; }练习场景函数同时返回和、差函数同时返回最大值、最小值。值传递拷贝一份数值地址传递拷贝地址被调可以操作主调原始内存。六、指针常见坑1. 野指针指针变量没有初始化里面是随机垃圾地址指向不明解引用程序崩溃。int *p; //野指针2. NULL空指针值为0号地址用来明确标记指针“不指向任何有效内存”避免野指针。int *p NULL; // 绝对不要解引用 NULL *p 程序崩溃3. 区分容易混淆写法int *p[4]; //指针数组数组4个int* int (*p)[4];//数组指针指针指向int[4]数组 char **p; //二级指针保存一级指针地址 void *p; //万能指针不能直接*p参考来源C语言指针详解指针—— char p[] 和 char *pC语言中的指针进阶[C语言]指针知识系统总结【C语言】char * 、char [ ]、const char * 和 void *的使用以及区别