为什么不用这个代码:a [i] = i ++; 工作?

Par*_*rag 2 c

a[i] = i++;
Run Code Online (Sandbox Code Playgroud)

为什么上面的代码不起作用?

上面的代码有什么问题?我问这个问题是为了提高我的知识水平.

pax*_*blo 9

因为ISO标准规定不允许多次更改变量(或更改并使用一个变量)而没有中间序列点.

还有就是利用之间没有顺序点i在a[i]和变化i中i++.

附件C中描述了来自C11的序列点列表(自C99以来没有那么多变化):

  • 在函数调用和实际调用中的函数指示符和实际参数的评估之间.
  • 在以下运算符的第一个和第二个操作数的计算之间:逻辑AND &&; 逻辑OR ||; 逗号,.
  • ?条件的第一个操作的评估之间:运营商和第二个和第三个操作数的为准评估.
  • 完整声明者的结尾:声明者;
  • 在评估完整表达式和下一个要评估的完整表达式之间.以下是完整表达式:初始化器; 表达式中的表达式; 选择语句的控制表达式(if或switch); while或do语句的控制表达式; for语句的每个表达式; 返回语句中的表达式.
  • 在库函数返回之前.
  • 在与每个格式化的输入/输出函数转换说明符相关联的操作之后.
  • 紧接在每次调用比较函数之前和之后,以及对比较函数的任何调用和作为参数传递给该调用的对象的任何移动之间.

并5.1.2.3 Program execution指出:

当A在B之前或之后进行测序时,评估A和B是不确定的,但是未指定哪一个.

在表达式A和B的评估之间存在序列点意味着在与B相关联的每个值计算和副作用之前,对与A相关联的每个值计算和副作用进行排序.

部分6.5 Expressions几乎涵盖了您的确切案例:

如果表达式的子表达式有多个允许的排序,则如果在任何排序中发生这种未测序的副作用,则行为是不确定的.

此段落呈现未定义的语句表达式,例如i = ++i + 1;和a[i++] = i;允许i = i + 1;和a[i] = i;.