【问题标题】:for loop: make increment and accessing in one loopfor循环:在一个循环中进行增量和访问
【发布时间】:2020-10-11 14:53:40
【问题描述】:

我不知道为什么这给了我垃圾:

#include <stdio.h>
int main(){
int a[10];
for(
    int i =0;
    i++<10;
    a[i-1]=i
   )
 {
  printf("%i:%i\n", i-1, a[i-1]);
 }
}

这给了我:

0:1676584240
1:32609
2:0
3:0
4:-1577938528
5:21992
6:-1577938864
7:21992
8:2114427248
9:32766

索引看起来是正确的,甚至循环内的分配也是正确的(例如,printf("%i\n",a[0]) 在循环之后给出了正确的 1)。但是在 for 循环体内, printf 尽管有正确的索引,但给出了错误的值(一些垃圾)。这是为什么呢?

编辑,在用... &amp;&amp; (a[i]=i) 回答了一些问题后,我尝试用其他语句来做到这一点:

for(
 int i = 0;
 i<10 && (a[i]=i);
 (i++) && printf("%i\n", a[i])
 );

但这不会打印任何内容,只会发出警告:

warning: value computed is not used [-Wunused-value]
   i++ && printf("%i\n",a[i])

为什么?当我可以做出(a[i]=i)的“真实”陈述时,为什么我不能做出(i++)的“真实”陈述?

【问题讨论】:

  • “给出错误的值” - 正确的值是什么?
  • 1,2,3,4,5,6,7,8,9,10
  • 你知道a[ ]没有初始化吗!所以它有一些很好的垃圾值!
  • 您首先打印未初始化的值,然后才为其分配一个有效值。
  • 你做a[i-1]=i 之后你打印了,太晚了

标签: c for-loop


【解决方案1】:

在做

for(
    int i =0;
    i++<10;
    a[i-1]=i
   )
 {
  printf("%i:%i\n", i-1, a[i-1]);
 }

您在打印它们之后设置条目 因为a[i-1]=ifor 的主体之后执行,所以您打印未初始化的数组条目

您的代码也很“复杂”,因为您在for 的测试部分中过早地增加了 i,这是一种执行您(可能)想要的“标准”方法:

for(int i = 0; i < sizeof(a)/sizeof(*a); ++i) {
  a[i]=i+1;
  printf("%i:%i\n", i, a[i]);
}

如果您真的不想在正文中包含a[i]=i+1;,您可以这样做:

for(int i = 0; (i < sizeof(a)/sizeof(*a)) && (a[i]=i+1); ++i) {
  printf("%i:%i\n", i, a[i]);
}

避免编译时出现警告 do ... &amp;&amp; ((a[i]=i+1) != 0);

注意(a[i]=i+1) 不是假的,因为值至少为 1,如果你想做a[i]=i,当 i 为 0

但这无助于阅读代码^^

【讨论】:

  • 请查看我的编辑。我已经更改了头部的最后一个表达式,但没有打印任何内容。如何解决这个问题?
  • @milanHrabos 在我说的地方重读我的答案:注意(a[i]=i+1) 不是假的,因为值至少为 1,以防你想做a[i]=i 使用的测试可以是(i &lt; sizeof(a)/sizeof(*a)) &amp;&amp; (a[i]=i, 1) 不是当 i 为 0 时为 false
【解决方案2】:

for 循环由 4 个部分组成:

  1. 初始化
  2. 条件
  3. 正文代码
  4. 动作

例子:

 for (initialisation; condition; action)
 {
     Body code
 }

执行顺序如我上面列举的那样。

在你的例子中,

for (int i = 0; i++ < 10; a[i-1])
{
    printf("%i:%i\n");
}
  1. 初始化 - i = 1
  2. 条件 - i++ &lt; 10; --> 0 &lt; 10 = true, i = 1
  3. 正文代码 - printfi=1a[0] 仍然未初始化
  4. 操作 - a[i-1] = ia[0] = 1(现在才初始化 a[0]

【讨论】:

    【解决方案3】:

    在您的代码中,您首先执行括号中的代码,然后分配数组。它必须以正确的相反方式完成。

    #include <stdio.h>
    int main()
    {
        int a[10];
        for(int i =0; i++, i <= 10 && (a[i-1] = i);)
        {
            printf("%i:%i\n", i-1, a[i-1]);
        }
    }
    

    https://godbolt.org/z/r-DvJi

    或更好

    #include <stdio.h>
    int main()
    {
        int a[10];
        for(int i = 0; i < 10 && (a[i] = i + 1); i++)
        {
            printf("%i:%i\n", i, a[i]);
        }
    }
    

    【讨论】:

    • for(int i=0;i++&lt;10 &amp;&amp; (a[i-1]=i); printf("%i\n",a[i-1])); 是最好的选择
    • 不知道我可以指定为“真实”条件,这似乎是一种魔法
    • @milanHrabos 实际上在第一个(答案中不存在)选项中我犯了一个错误。一般是UB
    • 查看我的编辑。我已经更改了 for 循环中的最后一个表达式,但无济于事
    • i++ 必须从条件出发
    猜你喜欢
    • 2014-12-12
    • 2019-01-17
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    相关资源
    最近更新 更多