You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何用对象指针批量打印数组会出现结果倒序?

为什么批量打印对象数组时输出倒序?

这其实是C/C++里未定义行为导致的典型问题,核心原因是函数参数/表达式子项的求值顺序没有强制标准,咱们一步步理清楚:

先看你批量打印的那行代码:

cout << ((p++)->GetTires()) << " " << ((p++)->GetTires()) << " " << ((p++)->GetTires()) << " " << ((p++)->GetTires()) << endl;

你在这里把4个带副作用的操作(p++)塞进了同一个表达式里——而C/C++标准从来没规定过这类场景下子表达式的求值顺序,不同编译器(甚至同一编译器不同优化等级)可能选择从左到右、从右到左,或者其他奇怪的顺序。

你的编译器刚好选择了从右往左求值这4个(p++)->GetTires(),而且每个求值的副作用(p自增)会立即生效,具体过程是这样的:

  1. 初始p指向数组第一个元素array[0];
  2. 编译器先计算最右侧的(p++)->GetTires():先读取当前p指向的array[0]的值(2),然后p自增指向array[1];
  3. 接着计算倒数第二个表达式:读取array[1]的值(4),p自增指向array[2];
  4. 再计算倒数第三个:读取array[2]的值(6),p自增指向array[3];
  5. 最后计算最左侧的表达式:读取array[3]的值(8),p自增指向数组末尾;
  6. 而cout的<<是左结合的,会按从左到右的顺序输出这四个表达式的结果——也就是8、6、4、2,刚好是倒序。

而你拆分到多个cout语句的情况就完全不同了:

cout << ((p++)->GetTires()) << " ";
cout << ((p++)->GetTires()) << " ";
// ...

每个cout都是一个独立的完整表达式,C++标准规定每个完整表达式结束后,所有副作用(比如p++的自增)都会被处理完毕。所以每一行都会先读取当前p指向的元素值,再自增p,自然就能按顺序输出2、4、6、8。

总结一下要注意的点:

  • 永远不要在同一个表达式中多次对同一个对象执行带副作用的操作(比如自增、自减、赋值),这属于标准明确规定的未定义行为,结果完全不可预测;
  • 如果需要按顺序操作,一定要拆分到不同的语句,或者使用有明确序列点的语法(比如逗号运算符,但注意参数列表里的逗号是分隔符,不是逗号运算符)。

内容的提问来源于stack exchange,提问作者A.H.M. Annur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:27:16