我试图在for循环的条件下在数组中分配值:
#include <iostream>
using namespace std;
int* c;
int n;
int main()
{
scanf("%d", &n);
c = new int[n];
for (int i = 0; i < n; c[i] = i++ )
{
printf("%d \n", c[i]);
}
return 0;
}
但是,对于n = 5,0 1 2 3 4
,我无法获得所需的输出。相反,如果我使用指令c[i] = ++i
,我将获得输出-842150451 1 2 3 4
。能否请您解释一下我们的代码是否像这样,我该如何纠正呢?
答案 0 :(得分:8)
表达式++i
的值是 i
递增后的值。因此,如果它从0开始,则第一次分配值1,依此类推。您可以看到其中已分配的值,但询问为什么它已分配给那里打开了一堆蠕虫。
在通过i
或 i
修改i++
的表达式中使用++i
是未定义的行为,除非存在所谓的“序列点“介于两者之间。在这种情况下,没有。有关此语言相当复杂的部分,请参阅Undefined behavior and sequence points。
虽然标准未对行为进行定义,但从一次运行到另一次运行可能不一致,显然您的程序已完成某些事情。显然它根本没有分配给索引0(至少,不是在第一次打印之前,考虑到循环体在“for”的最后部分之前发生,这是可以理解的),所以你当它被分配给你时,得到的只是在原始记忆中发生的事情。它将1
分配给索引1
,依此类推。
这意味着它也可能尝试将值5
分配给c[5]
,这是一类被称为“缓冲区溢出”的错误,并且在您之上有更多未定义的行为已经有了。 尝试分配给它可能会覆盖其他内存,这些内存在任何一天都可能包含或不包含重要内容。
修复方法是为c[0]
分配一些值,并且不要尝试分配到c[5]
,但这样做并不存在,并且不要试图无效地使用i
}“在增加它的同时。通常你会这样写:
for (int i = 0; i < n; ++i) {
c[i] = i;
printf("%d \n", c[i];
}
如果你因为某种原因而不顾一切地在for循环的第三个子句中进行分配,你可以使用逗号运算符来引入一个序列点:
for (int i = 0; i < n; c[i] = i, ++i) {
}
但是当然如果你这样做那么你就不能在循环体中打印c[i]
的值。它尚未分配,因为直到每个循环结束才会计算第三个子句。
您也可以尝试c[i] = i+1, ++i
,但不 ++i, c[i] = i
因为我们会在最后一次迭代时重新尝试分配给c[5]
。< / p>
答案 1 :(得分:2)
首先你需要了解for循环的最后一部分是在每次迭代的 end 处执行的,所以你看到这个原因:
-842150451 1 2 3 4
是因为您在分配之前打印c[0]
,因此值可以是任何值。其余部分符合预期。
课程;不要偷偷摸摸地将东西塞进for循环的最后一部分。让您的代码清晰简单:
for (int i = 0; i < n; ++i )
{
c[i] = i;
printf("%d \n", c[i]);
}
答案 2 :(得分:2)
首先,您声称要在“循环条件”内分配值。在for
循环中,条件是标题的第二部分(在您的情况下为i < n
)。您正在第三部分中执行分配,即不条件。那么,你为什么要说你想在条件中分配值,但却没有这样做呢?
其次,像c[i] = i++
或c[i] = ++i
这样的表达式在C ++语言中没有任何已定义的行为。在C ++中,修改变量是非法的,同时在没有插入序列点的情况下将其读取用于任何其他目的。然而,你正是这样做的。对代码的行为没有任何有意义的解释。代码的行为是 undefined 。它可以为任何随机原因做任何事情。
第三,初始化for
条件下的任何内容通常都不是一个好主意。你能更详细地解释一下你想做什么以及为什么?没有它,很难想出任何有意义的东西。
答案 3 :(得分:1)
c[i] = ++i
产生未定义行为的原因。 ++
值(前置或后置)未定义,并在同一表达式中再次使用它。在这种情况下,似乎++i
在其他任何事情之前被评估,并导致执行基本上是
c[1] = 1;
c[2] = 2;
...
这意味着c[0]
永远不会被初始化,而是基本上具有垃圾值。看起来你想要的订单是
c[0] = 0;
c[1] = 1;
要获得此排序,您需要将初始化和增量分成单独的语句。
c[i] = i;
i++;
答案 4 :(得分:1)
你的基本问题是for(;;)结构中的语句如何被分解和执行。 for(st1; st2; st3)结构旨在与:
相同st1;
while (st2) {
<body>
st3;
}
因此,您的第3个语句c[i] = i++
在 printf
语句之后执行,并且您正在打印未初始化的数据。
预增量与后增量问题模糊了这一点。