C语言printf传入多个*p++参数输出结果与预期不符问题
异常输出原因分析
根本原因:C标准未定义函数实参的求值顺序
C语言规范没有强制要求编译器对函数调用的多个实参按照固定顺序求值,编译器可以根据自身实现、优化策略自由选择求值顺序,你遇到的输出是当前编译器选择从右到左求值实参导致的。
代码执行过程拆解
你第四行的测试代码为:
printf("%d %d %d\n", *p++, *p++, *p++);
运行该行代码前,指针p初始指向数组a的首元素a[0](存储值为10),编译器从右到左求值三个参数的过程如下:
- 先计算最右侧第三个参数
*p++:后缀自增优先级高于解引用,先取p自增前的地址解引用得到值10作为该参数的结果,随后p自增指向a[1](存储值为20) - 再计算中间第二个参数
*p++:取p当前指向的值20作为该参数的结果,随后p自增指向a[2](存储值为30) - 最后计算最左侧第一个参数
*p++:取p当前指向的值30作为该参数的结果,随后p自增指向数组边界外的非法地址
printf输出时会按照占位符从左到右的顺序输出参数结果,因此最终输出为30 20 10,和你实际运行的结果一致。
注意:在同一段序列点内多次对同一个变量执行带副作用的操作(比如自增、自减、赋值)属于C语言的未定义行为,不仅不同编译器的输出结果可能不同,同一编译器开启不同优化选项时的结果也会发生变化,日常开发中要严格避免编写这类代码。
内容的提问来源于stack exchange,提问作者박고은
相关产品推荐
相关产品推荐

