C++中前置++与后置++问题:数组赋值结果不符求助
你遇到的是C++里的经典未定义行为坑!
嘿,我来帮你拆解这个问题:你的核心问题出在循环体里的v[i] = i++这个表达式上——在C++17标准之前,这个表达式属于未定义行为,编译器可以自由选择执行顺序,这直接导致实际输出和你的预期不符。
为什么会出现这样的结果?
假设m的值是3,我们一步步看实际发生的过程:
- 你用
new int[m]创建的数组是未初始化的,所以v[0]、v[1]、v[2]的初始值是随机的(你输出里v[1]是0只是巧合,换个环境可能就是别的数)。 - 第一次循环:
i=0,执行v[i] = i++。如果编译器选择先定位到v[0](此时i还是0),再把i自增到1,最后把旧值0赋值给v[0],这一步和你的预期一致,得到v[0]=0。 - 第二次循环:
i=1,执行v[i] = i++。如果编译器这次换了顺序——先把i自增到2,再定位到v[2],最后把旧值1赋值给v[2]——那v[1]就还是未初始化的随机值(你的输出里是0),v[2]被设为1。 - 第三次循环:
i=2,执行v[i] = i++。编译器继续按第二次的逻辑,先把i增到3,再把旧值2赋值给v[3](这已经是数组越界了,属于非法操作,但不会立刻报错)。
最终就出现了你看到的输出:0 0、1 0、2 1。
怎么修复?
要避开这个坑,你只需要把i的自增和数组赋值的操作分开,让执行顺序完全明确:
void build(int *&v) { v = new int[m]; for (int i =0; i<m; i++){ v[i] = i; // 先赋值,再通过for循环的i++完成自增 } for (int i=0;i<m;i++){ cout <<i << " " << v[i] <<endl; } }
如果你一定要在循环体里处理自增,也可以写成这样:
for (int i =0; i<m;){ v[i] = i; i++; // 明确先赋值,再手动自增 }
这样就能保证每次都是先把当前的i赋值给v[i],再让i自增,完全符合你的预期。
内容的提问来源于stack exchange,提问作者Hball99
相关产品推荐
相关产品推荐

