指针操作后如何获取指向的真实值?代码运行结果不符预期
问题分析与解决方案
你的问题核心是运算符优先级理解错误,导致指针操作的行为和预期完全不符,我们一步步拆解清楚:
1. 问题到底出在哪?
看代码里的关键行:
*(pd)++;
你可能以为这是先解引用指针pd,再对指针本身做偏移;或者误以为是对指针指向的值做自增?实际上C语言里后置++的优先级高于解引用*,哪怕你给pd加了括号,也改变不了这个优先级规则——括号只是确保pd作为整体被处理,但后置++依然会先作用在指针上。
这行代码等价于:
*(pd++);
执行顺序是:
- 先把指针
pd向后偏移一个float类型的长度(也就是4字节,所以地址从1539432628变成1539432632) - 再对偏移后的指针进行解引用
此时pd已经不再指向原来的value变量,而是指向栈上value后面的未知内存区域,这里的内容是随机的垃圾数据,所以你输出的*pd才会是一个离谱的大数。
2. 如何实现你的预期?
你的预期是“操作前后指针指向的真实值一致”,需要先明确你的真实需求:
- 如果只是想临时移动指针,但之后还要访问原来的
value:那你得先保存原指针的地址,比如:float *original_pd = pd; // 保存原指针地址 pd++; // 移动指针 printf("%p\n", (void*)pd); printf("%f\n", *original_pd); // 访问原地址的value值 - 如果你其实是想对指针指向的
value值做自增操作,而非移动指针:那必须用括号把*pd括起来,确保先解引用拿到值,再对值做自增:(*pd)++; // 先解引用得到value,再对value的值+1 printf("%p\n", (void*)pd); // 指针地址完全不变 printf("%f\n", *pd); // 输出13.345000(原12.345+1)
3. 额外的规范提示
输出指针地址时,用%d是不标准的,应该用%p格式符,并且把指针强制转换成void*类型:
printf("%p\n", (void*)pd);
这样才能符合C语言的跨平台规范,避免不同架构下的地址输出错误。
最后附上修正后的代码(以“修改值但不移动指针”的需求为例):
#include <stdio.h> int main() { float value; float *pd; printf("input float value : "); scanf("%f", &value); pd = &value; printf("%p\n", (void*)pd); printf("%f\n", *pd); (*pd)++; // 正确的对值自增操作 printf("%p\n", (void*)pd); printf("%f\n", *pd); return 0; }
内容的提问来源于stack exchange,提问作者EqualLove
相关产品推荐
相关产品推荐

