【问题标题】:How does the value get assigned in the array in that specific index? [duplicate]如何在该特定索引的数组中分配值? [复制]
【发布时间】:2021-10-17 08:25:56
【问题描述】:

当我运行以下代码时,我得到输出:0 0 2 0 0

int main(){

    static int var[5];
    int count=0;
     
    var[++count]=++count;
    for(count=0;count<5;count++)
    { 
      printf("%d ",var[count]);
    }
    return 0;
}

【问题讨论】:

    标签: arrays c assignment-operator pre-increment


    【解决方案1】:

    根据 C17 标准 6.5.2,声明 var[++count]=++count; 会引发未定义的行为:

    如果标量对象上的副作用相对于同一标量对象上的不同副作用或使用同一标量对象的值的值计算是未排序的,则行为未定义。如果一个表达式的子表达式有多个允许的排序,并且在任何排序中出现这种未排序的副作用,则行为是未定义的。)

    因此,对于每个唯一变量,它认为如果它是预先递增的,那么它的值可能不会在该表达式的其他地方使用。结果将是变量首先递增,然后在表达式中使用其递增的值。

    代码在技术上是未定义的行为。在实践中(可能)发生的事情是,count 增加了两次,然后同时用作索引和值。

    【讨论】:

    • 好点,谢谢!我已经更新了答案。
    • 我相信如果只有一个“计数”用途被预先索引,它也将是未定义的。表达式是模棱两可的,结果随选择的执行顺序而变化。没有隐含的从左到右或从右到左的顺序。句法分析树的元素可以按任何顺序执行——包括不一致。尽管编译器可能会检测到这种情况,但如果“count”是一个函数,例如“Count()”,则可能会出现更简单的情况。编译器在生成调用的代码时可能不知道“Count()”的操作它。
    • “因此,一个表达式中只能使用一个预增量运算符”是不正确的,原因有多种:预增量运算符可以用于不同的左值,并且某些表达式包括呈现多种用途的排序定义的预增量运算符(和其他)。
    • @cmm:“句法分析树的元素可以按任何顺序执行”:这并不完全正确,尽管它不会影响手头的情况。更新= 的左操作数的存储值的副作用在左操作数和右操作数的值计算之后排序(C 2018 6.5.16 3)。因此,如果有人写了x = 3; x = (f(x), 4);f 必须用参数 3 来调用;不能先进行 4 的赋值。 (逗号运算符也有一个序列点,但它只对自己的操作数进行排序;它不会影响除此之外的表达式。)
    • 埃里克,同意了。我将我的想法限制在未排序运算符的树上。如果我没记错的话,您的示例上下文中的逗号(其作用类似于 LISP prog2 函数)序列,但它不会在参数列表的上下文中序列。可以按任何顺序评估参数。
    猜你喜欢
    • 2018-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    • 2019-11-16
    相关资源
    最近更新 更多