C语言对指针解引用执行自增操作后为何返回无效值
问题根因
出问题的核心是踩了C语言运算符优先级的坑,你写的*j++完全没有实现「给i自增」的预期逻辑:
- 后缀自增运算符
++的优先级比解引用运算符*高,*j++的实际执行逻辑是*(j++),不是你以为的(*j)++ - 后缀自增的特性是「先返回变量原来的值,再给变量本身加1」,所以这里
j++会先返回j存的原地址(也就是i的地址),*拿到这个地址对应的值(也就是i=3)之后,你没有对这个值做任何操作,等于白读了一次i - 等整个表达式执行完,j本身已经被加了1——作为int类型指针,j会向后偏移1个int的长度,直接指向了i旁边的未知栈内存,已经变成野指针了。这时候你再解引用j,读到的就是栈上的随机垃圾值,也就是你看到的类似地址的无效数据,和i没有任何关系。
- 额外提个小问题:你用
%u格式符打印int类型值是不规范的,%u对应无符号整型,普通int打印应该用%d,不过这个不是本次运行结果异常的主要原因。
修正方案
要实现「j保持指向i,把i的值加1」的效果,必须加括号强制运算顺序,让自增作用在解引用拿到的i上:
#include <stdio.h> int main() { int i = 3, *j; j = &i; printf("\nValue of i = %d", *j); (*j)++; // 先解引用拿到i,再对i做自增,j本身的指向不变 printf("\nValue of i = %d", *j); return 0; }
编译运行后会依次输出3和4,完全符合预期。
指针相关学习参考
- 入门阶段先看《C Primer Plus》的指针相关章节,对指针基础、地址运算、运算符优先级、指针和数组的关联讲得非常细致,覆盖了新手最容易踩的绝大多数坑
- 想针对性强化指针用法可以读《C和指针》,整本书围绕指针的正确使用、常见误用场景展开,配合大量示例帮你建立对指针的正确认知
- 学习过程中不要靠直觉猜表达式的执行逻辑,多写几行测试代码打印指针地址、指针指向的值验证结果,碰到不确定优先级的场景直接加括号明确运算顺序,是成本最低的避坑方式。
内容的提问来源于stack exchange,提问作者Tatai
相关产品推荐
相关产品推荐

