C语言中* a 和 *a 以及变量a 的区别,附上程序。经典swap方法
文章目录 C语言里的“套娃”游戏彻底搞懂 a, *a 和 *a 核心概念内存就像一栋大宿舍楼 逐个击破a, *a, *a 到底是谁 一张表总结 为什么我们要关心 *a 代码实战 总结作者代码demo C语言里的“套娃”游戏彻底搞懂 a, *a 和 *a很多初学 C 语言的朋友甚至包括一些老手在面对指针时经常会感到“头秃”。特别是当和*这两个符号像叠罗汉一样堆在一起时比如*a很多人就懵了这到底是啥和*a有啥区别和原本的变量a又是啥关系今天我们就用最通俗的语言把这个逻辑捋清楚。 核心概念内存就像一栋大宿舍楼为了理解这几个符号我们先得达成一个共识内存就像一栋巨大的宿舍楼。变量如a是住在某个房间里的“人”或者“物品”。地址如a是这个房间的“门牌号”。指针是一个小本子上面记录着某个人的房间号。在 C 语言中变量a本质上是一个存储单元。为了消除歧义C 语言规定直接用a代表房间里的人数据本身。用a代表房间的门牌号数据的地址。 逐个击破a, *a, *a 到底是谁假设我们有如下代码inta10;// 普通变量int*pa;// 指针 p 指向 a现在我们来看看这三个“主角”1. 变量 a实实在在的数据这是最直观的。a就是那个存储单元里存的具体数值。含义取变量a里的数据。结果10。人话翻译“我要找住在 805 房间的那个人。”2.a或者更准确的p顺藤摸瓜注意如果a是个普通int写*a会报错因为a不是地址。这里我们假设你问的是“指针解引用”这个动作或者a本身是个指针变量的情况。符号*叫做解引用符**。它的作用是“既然你给了我一个地址那我就顺着这个地址去把里面的人抓出来。”含义访问指针所指向的内存空间中的数据。结果10如果a是指针则代表a指向的值。人话翻译“我看了一下小本子指针上的门牌号然后去那个房间把人带出来。”3. a脱裤子放屁看似多余实则有用这是最让人晕的。是取地址*是取值。它俩碰到一起会怎样根据运算优先级*和优先级相同结合方向是自右向左*。所以*a的执行顺序是先执行*a找到a指向的那个目标也就是变量本身。再执行取这个目标的地址。结论*a在数学逻辑上等于a取变量地址。含义先找到指针指向的变量再取这个变量的地址。结果变量a的内存地址例如0x0012FF7C。人话翻译“我去那个房间把人找出来*a然后问问他住哪。” —— 听起来很傻对吧但在某些复杂的指针运算或宏定义中这种写法能确保类型匹配。 一张表总结表达式核心动作结果备注a取值数据 (如 10)如果 a 是指针这里取的是地址值*a解引用数据 (如 10)前提是 a 必须是指针a取地址内存地址获取 a 自身的地址*a先解引用再取地址内存地址等价于 a (当 a 为指针时) 为什么我们要关心 *a你可能会问“既然*a等于a那为什么不直接写a”在普通的变量操作中确实没区别。但在指针运算和结构体成员访问时这个逻辑很重要。例如如果你有一个指向结构体的指针pStruct你想访问成员member的地址写法一((*pStruct).member)—— 先解引用找到结构体再找成员再取地址。写法二(pStruct-member)—— 箭头操作符本质上就是*逻辑的简化版。 代码实战让我们看一段代码来验证一下#includestdio.hintmain(){inta100;int*pa;printf(a 的值: %d\n,a);// 输出: 100printf(*p 的值: %d\n,*p);// 输出: 100 (通过指针取值)printf(a 的地址: %p\n,a);// 输出: 0x... (a 的地址)printf(p 的值: %p\n,p);// 输出: 0x... (p 存的就是 a 的地址)// 重点来了*p// 先 *p 找到 a再 取 a 的地址printf(*p 的值: %p\n,*p);// 输出: 0x... (和 a 一模一样)return0;} 总结a是盒子里的东西。*a是拿着钥匙去开盒子取东西解引用。*a是先打开盒子找到东西再问这个东西在哪。虽然绕了一圈但结果就是那个东西的地址。理解了这一点你就掌握了 C 语言指针操作的“任督二脉”希望这篇帖子能帮你理清思路。你觉得这篇帖子的解释逻辑特别是“宿舍楼”的类比符合你的预期吗需要我帮你做进一步的优化吗比如增加实战案例补充一个*a在函数传参中的具体应用场景调整语气风格需要更严肃学术一点还是更幽默风趣一点精简篇幅如果用于发朋友圈或短动态我可以帮你浓缩到 300 字以内。作者代码demo错误程序并说明错误原因#includestdio.hvoidswap(int*a,int*b){// *a 本质是引用地址指针变量inttemp;temp*a;*a*b;*btemp;}intmain(){inta10,b20,temp;swap(a,b);// 这句会报错原因是方法中的 *a 无法引用到指针变量a 使用的不是指针变量传的只是值地址printf(%d\n,a);printf(%d,b);}修正后的程序#includestdio.hvoidswap(int*a,int*b){// *a 本质是引用地址指针变量inttemp;temp*a;*a*b;*btemp;}intmain(){inta10,b20,temp;int*a1a;int*b1b;swap(a1,b1);// swap(a,b); // 这句会报错原因是方法中的 *a 无法引用到指针变量a 使用的不是指针变量传的只是值地址printf(%d\n,a);printf(%d,b);}运行结果