C语言指针专题
1、 指针、地址、
一级指针、二级指针、一维数组与一级指针、二维指针与二维数组
数组指针、指针数组、函数指针、单引号、双引号
2、指针与地址
// 指针与地址 // 变量在被定义后就已经存在一个地址;变量可以变,但是地址不会变 // 指针用来保存变量的地址 // 指针本身也是一种变量类型; void testp() { int b =32; // 定义一个变量 int *p = NULL; // 定义一个指针变脸,保存int类型数据的地址 printf("b的地址:%x\n",&b); // 打印b的地址 p = &b; // 将数据地址传给指针变脸 printf("p保存的地址变量:%x\n",p); printf("通过指针拿到数据:%d\n",*p); /// 或者说通过指针传递数据 *p = 64; // 通过指针修改对应地址保存的数据 printf("通过指针修改对应地址的值:%d\n",b); }
3、一级指针与二级指针
// 一级指针、二级指针 // 一维数组、二维数组 void testp2() { int b = 16; // 定义一个int变量 int a = 32; int *p = NULL; // 定义一个一级指针 int **pp = NULL; // 定义一个二级指针 p = &b; // 一级指针存储常量地址; pp = &p; // 二级指针存储一级指针地址 *pp = &a; // 二级指针加引用退化为一级指针 printf("*(*pp))代表的值:%d\n",*(*pp)); // 取到a的值 }
4、一维数组与一级指针
// 数组与指针 void testp3() { int len = 0; int *p =NULL; int arr[16]={1,2,3,4,5,6,7}; p = &arr[0]; printf("一维数组第一个元素地址:%x\n",p); printf("一维数组名称地址:%x\n",arr); // 一维数组第一个元素地址 == 一维数组名称地址 len = sizeof(int*); // int类型指针大小; printf("sizeof(int*):%d\n",len); p += 1; printf("p=p+1地址内容:%d\n",*p); // *p == arr[1] printf("数组元素arr[1]:%d\n",arr[1]); }
5、数组指针与二维数组
// 二级指针与二维数组 // 数组指针与二维数组 void testp4() { /* 这两个之间没有直接关系 * 二维数组是数组的数组 * 数组名是地址,指针用来保存地址 **/ int x=0; int Arr[2][3]={2,3,4,5,6,7}; // 定义一个二维数组 int **pt = NULL; // 定义一个二级指针 int (*p)[3]; // 定义一个数组指针 //pt = Arr; // 无法将int (*)[3]类型的值分配到int**的实体 二维数组与二级指针没有直接联系 p = Arr; // 将p指针指向Arr[0]的地址,存放一个长度为8的数组 等价于p = &Arr[0]; p = &Arr[1]; // 将指针指向Arr[1]的地址,改地址存放一个长度为8的数组 for(x=0;x<3;x++) { printf("访问第一个元素:%d\n",(*p)[x]); // 数组指针 访问二维数组元素 } }
5、指针数组与二级指针
// 指针数组与二级指针 void testp5() { int* arr[3]; // 定义一个指针数组,指针修饰,本质是数组,保存变量为地址 int** px; // 定义一个二级指针,保存地址的地址 int num = 10; arr[0] = # // 这个元素用来保存一个地址;一级指针 printf("指针数组第一个元素是一个地址:%x\n",arr[0]); px = &arr[0]; // 等价于px = arr; 对地址取地址,就是指针的指针 printf("指针的指针:%x\n",px); **px = 20; // 改变num的值 printf("二级指针取变量:%d\n",**px); printf("改变num值:%d\n",num); }
6、字符串与数组、指针
// 指针定义字符串与数组定义字符串 void testp6() { char arr1[]="abcdef"; // 数组定义字符串 字符串中的元素可以修改 char* ps = "mngled"; // 指针定义字符串 字符串中的元素不可以修改 int i = 0; arr1[1] = 'T'; // 改变数组中的元素 printf("arr1数组字符串:%s\n",arr1); printf("指针中的元素:%c\n",ps[5]); //字符串中最后一个字符但是不会打印出来,"\n" //ps[1] = 'D';// 在这里出现异常 //printf("指针中的字符串:%s\n",*ps); // VS2012运行在这里没有输出结果 for(i=0;i<6;i++) { if(*(ps+i) == 'l') // 查找字符串中存在的字符,并输出 printf("指针地址加1:%c\n",*(ps+i)); } }
7、单引号与双引号
// "T"与'T'区别 void testp7() { char c = 'C'; char *b = "abc"; // 如果定义char b = "abc"; 报错 // 表示含义不一样:单引号引起的,是一个字符,与ASCII码表对应的整数对应 // 双引号表示:指向一个无名数组起始字符的指针 //大小不一样:字符串比字符多一个结束字符 }
8、函数指针
// 函数指针 // 指针函数、函数指针 int Sum(int a,int b) { return a+b; } void testp8() { // 指针函数:函数返回值一个指针 // 函数指针:指针存放函数地址,调用函数,做函数的参数 typedef void (*func)(int x,int y); int (*pfunc)(int a,int b); // 定义pfunc为一个函数指针,存储前面形式的函数地址 pfunc = Sum; //调用函数 printf("求和结果:%d\n",pfunc(12,23)); }
指针贯穿整个C语言环境,后续用到了再继续添加
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】开源 Linux 服务器运维管理面板 1Panel V2 版本正式发布
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Java线程池详解:高效并发编程的核心利器
· 从“看懂世界”到“改造世界”:AI发展的四个阶段你了解了吗?
· 协程本质是函数加状态机——零基础深入浅出 C++20 协程
· 编码之道,道心破碎。
· 记一次 .NET 某发证机系统 崩溃分析
· dotnetty 新的篇章- 开源
· 这5种规则引擎,真香!
· DotTrace系列:1. 理解四大经典的诊断类型(上)
· 【大数据高并发核心场景实战】 - 数据持久化之冷热分离
· 如何用大语言模型提取任意文档中的知识点