【问题标题】:i+1 as opposed to i++i+1 与 i++ 相对
【发布时间】:2021-02-10 02:36:45
【问题描述】:

为什么i++;给我奇怪的随机数,而不是i + 1;在for循环中? 我对编程很陌生,所以我想了解这里的区别。 我的猜测是 i 以某种方式被覆盖,这使得编译器从内存中取出随机数。

#include <stdio.h>

int main() {
    int arr[100];

    for (int i = 0; i < 100; i++) {
        arr[i] = i + 1; //why wouldn't i++ work?
    }

    return 0;
}

【问题讨论】:

标签: arrays c for-loop undefined-behavior post-increment


【解决方案1】:
arr[i] = i+1;

很好,将i + 1 分配给arr 中的元素i

arr[i] = i++;

未定义的行为: 在为arr[i] 读取i 和在i++ 中修改它之间没有排序。一切顺利。

【讨论】:

    【解决方案2】:

    i + 1 计算 i 加上 1 的值。它将i 的值偏移1

    i++ 产生i 的当前值,但之后立即增加i。这会打乱你的循环,有效地跳过地方。

    这里的区别在于+ 运算符不会改变任何一个值,而是生成一个新值,而++ 运算符会更改它所附加的值。 p>

    【讨论】:

    • 非常感谢您的解释! :)
    【解决方案3】:

    i++ 是后缀递增运算符,这意味着它递增 i 然后返回 i 的旧值。因此,在第一个循环中,您将 0 写入arr[0],然后i 将递增到1,然后再次通过循环到2,然后2 将写入arr[2] ,而i 将变为4,以此类推。因此,每个其他值都会有索引,而其他值将有随机未初始化的内存。

    【讨论】:

    • 无法保证分配左侧使用了i 的哪个值。 a[i] = i++; 是 UB。
    【解决方案4】:

    鉴于此代码:

        int arr[100];
    
        for (int i = 0; i < 100; i ++) {
            arr[i] = i+1; //why wouldn't i++ work?
        }
    

    ...在循环体中用i++ 替换i + 1 存在两个 问题:

    1. 计算表达式i++ 会更新i 的值,计算表达式a[i] 会读取i 的值。因为在你的赋值中这些表达式的计算相对于彼此是“无序的”,所以结果行为是未定义的。这允许任何事情发生,而不仅限于选择一种或另一种评估顺序的效果。

    2. 假设 (1) 在给定的实现中不是问题——它提供了一个扩展,例如,对赋值的左操作数的求值在对该赋值的右操作数的求值之前进行排序。在这种情况下,如果您修改示例代码,将循环体中的表达式i++ 替换为表达式i+1,则结果是i 每次迭代都会递增两次环形。在这种情况下,只有一半的数组元素会被循环赋值。没有初始化器声明的局部变量的值在显式分配之前是不确定的。读取未分配元素的值可能会产生任何结果。

    【讨论】:

    • 非常感谢您的详尽解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    • 2015-05-24
    • 2014-02-22
    • 2020-05-24
    相关资源
    最近更新 更多