数组初始化

时间:2011-03-03 00:35:58

标签: c++

我试图在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。能否请您解释一下我们的代码是否像这样,我该如何纠正呢?

5 个答案:

答案 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语句之后执行,并且您正在打印未初始化的数据。

预增量与后增量问题模糊了这一点。