尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

从零开始的敲代码生活--C语言篇(指针)

从零开始的敲代码生活--C语言篇(指针) C语言指针完整整理文档一、指针基础概念1. 核心定义内存地址计算机以字节为单位给内存编号编号就是地址指针 地址二者等价指针变量专门存放内存地址的变量普通变量存数值指针变量存地址2. 指针变量定义语法格式基类型 * 变量名基类型决定指针解引用时访问多少字节*表示该变量是指针不是普通变量int *pint; // 存放int变量地址解引用访问4字节 char *pch; // 存放char变量地址解引用访问1字节 double *pd; // 存放double地址解引用访问8字节 int *p1, *p2; // 同时定义两个int指针每个都要加*注意64位系统所有指针统一占8字节32位系统占4字节和基类型无关3. 取地址、解引用*运算符 取地址符作用获取变量首字节地址限制只能作用于变量不能给常量、表达式取地址int num 10; int *p num; // p保存num的地址 解引用符作用通过地址访问对应内存中的数据p地址值*p地址对应存储的数据*p 100; // 修改num的值为1004. 野指针与空指针野指针未初始化、指向已释放内存的指针访问会段错误空指针NULL值等价0代表不指向任何有效空间 规范写法定义指针时默认初始化为NULLint *p NULL; // 安全初始化避免野指针5. 指针算术运算仅、-有意义* / %不能用于指针指针±数字偏移数字×sizeof(基类型)字节char *pc; pc1 // 向后偏移1字节 int *pi; pi1 // 向后偏移4字节同类型指针相减结果是两个指针之间元素个数 公式元素个数 (p2 - p1) / sizeof(基类型)指针不支持相加、相乘等运算二、指针与一维数组1. 数组名本质数组名是数组首元素的地址常量不可赋值axxx非法int a[5] {1,2,3,4,5}; a a[0]; a[2] *(a 2); // 下标等价解引用写法2. 数组作函数参数数组形参会退化为指针两种等价写法void print(int a[], int len); void print(int *a, int len);补充函数内sizeof(a)得到指针大小(8字节)不是数组总长因此必须传长度参数3. 字符指针与字符数组区分char str1[] hello; // 栈数组内容可修改 char *str2 hello; // 指针指向只读常量区*str2x段错误三、数组指针 vs 指针数组极易混淆1. 数组指针int (*p)[5]本质指针指向一整个长度为5的int数组a才是数组指针类型a1直接跳过整个数组空间2. 指针数组int *p[5]本质数组数组每个元素都是int*指针常见用途存储多个字符串常量char *arr[3] {aaa, bb, c};二者内存大小对比64位char str[3][100]; // 二维字符数组 300字节 char *p[3]; // 指针数组 3*824字节四、指针与二维数组二维数组名是一维数组指针int (*)[列数]int a[2][3]; a a[0]; a[1] *(a1); a[1][2] *(*(a1)2);函数传参规范列数不能省略void show(int arr[][3], int row); void show(int (*arr)[3], int row);五、二级指针1. 定义int **pp保存int*类型变量的地址2. 两大使用场景函数内修改外部指针变量需要传指针的地址指针数组的数组名天然是二级指针char *p[5]; char **pp p; // p等价p[0]类型char**三级传参对比值传递(普通变量)无法修改外部变量一级指针传参可修改外部普通变量二级指针传参可修改外部指针变量六、const修饰指针const int *p / int const *p指针指向的值只读指针本身可改指向p num2; // 合法 *p 100; // 报错int * const p指针指向固定不可改指向的数据可修改p num2; // 报错 *p 100; // 合法const int * const p指针指向、指向数据均只读定义必须初始化七、万能指针 void*void*可接收任意类型指针地址不能直接解引用使用前强制转换对应类型void *p num; int val *(int*)p;用途malloc返回值、通用回调函数参数八、指针函数 函数指针1. 指针函数返回值是指针的函数格式char* func(int x);限制不能返回局部栈变量地址函数结束内存销毁 合法可返回static局部变量、全局变量、字符串常量、堆地址、传入的参数地址2. 函数指针指向函数的指针格式int (*pfun)(int,int);int add(int a,int b){return ab;} int (*pf)(int,int) add; pf(1,2); // 通过指针调用函数拓展回调函数核心载体降低代码耦合九、动态内存(malloc/free)与指针堆内存只能用指针接收栈自动释放堆必须手动freechar *buf (char*)malloc(100); if(buf NULL) {perror(分配失败); return -1;} // 使用内存 free(buf); buf NULL; // 置空防止野指针注意不free会造成内存泄漏十、高频易错点数组名是地址常量不能a p函数内数组退化为指针无法通过sizeof求数组总长字符串常量指针char *sxxx不可修改内容一级指针改普通变量二级指针改指针变量区分int (*p)[N]数组指针、int *p[N]指针数组括号优先级自增p改变指针本身(*p)改变指向的数据。
返回列表