提问人:Sanjay Kumar 提问时间:8/14/2021 最后编辑:user438383Sanjay Kumar 更新时间:8/15/2021 访问量:86
如何在该特定索引的数组中分配该值?[复制]
How does the value get assigned in the array in that specific index? [duplicate]
问:
当我运行以下代码时,我得到输出: 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;
}
答:
1赞
Yun
8/14/2021
#1
该语句根据 C17 标准 6.5.2 诱导未定义的行为:var[++count]=++count;
如果标量对象上的副作用相对于同一标量对象上的不同副作用或使用同一标量对象的值进行值计算未排序,则行为未定义。如果表达式的子表达式有多个允许的排序,则如果在任何排序中出现这种未排序的副作用,则行为是未定义的。
因此,对于每个唯一变量,它认为如果它是预先递增的,那么它的值可能不会在该表达式的其他位置使用。结果是变量首先递增,然后在表达式中使用其递增值。
该代码在技术上是未定义的行为。在实践中(可能)发生的事情是,它被递增两次,然后同时用作索引和值。count
评论
0赞
Yun
8/14/2021
好点子,谢谢!我已经更新了答案。
1赞
cmm
8/14/2021
我相信,如果只预先索引了一种“计数”用途,它也将是未定义的。表达式不明确,结果随所选的执行顺序而变化。没有隐式的从左到右或从右到左的顺序。语法解析树的元素可以按任何顺序执行,包括不一致的顺序。尽管编译器可能会检测到这种情况,但如果“count”是一个函数,例如“Count()”,则可能会出现更简单的情况。编译器在生成调用它的代码时可能不知道“Count()”的操作。
0赞
Eric Postpischil
8/14/2021
“因此,一个表达式中只能使用一个预增运算符”是不正确的,原因有很多:预增运算符可以用于不同的左值,并且某些表达式包括序列,这些排序使预增量运算符(和其他运算符)的多次使用被定义。
0赞
Eric Postpischil
8/14/2021
@cmm:“句法解析树的元素可以按任何顺序执行”:这并不完全正确,尽管它不会影响手头的情况。更新左操作数的存储值的副作用是在左操作数和右操作数的值计算之后排序的(C 2018 6.5.16 3)。因此,如果有人写了 ,必须用参数 3 来调用;不能先执行 4 的赋值。(逗号运算符也有一个序列点,但它只对自己的操作数进行排序;它不会影响该操作数之外的表达式。=
x = 3; x = (f(x), 4);
f
0赞
cmm
8/14/2021
埃里克同意了。我把我的想法限制在树上,用于未排序的运算符。如果我没记错的话,您的示例上下文中的逗号(类似于 LISP prog2 函数)会进行排序,但它不会在参数列表的上下文中进行排序。参数可以按任何顺序进行评估。
评论