下标运算符的评估顺序

时间:2011-09-26 14:14:58

标签: c arrays expression

在数组的情况下是否存在任何评估表达式的顺序。 如果表达式E具有E1 [E2]的形式,其中E1& E2也是表达式,是E1&的评估顺序。 E2固定?

这是我的代码:

#include<stdio.h>
int main(){

    int a[5] = {1,2,3,4,5}; 
    (a + printf("1"))[printf("2")];
    (printf("3"))[a + printf("4")];

    return 0;
}   

它显示输出为: 1243

我用gcc编译了它。

感谢。

4 个答案:

答案 0 :(得分:7)

E1[E2]相当于*(E1 + E2)

标准告诉我们“子表达式的评估顺序和副作用发生的顺序都是未指明的”。因此,E1[E2]的评估顺序并不固定。

答案 1 :(得分:3)

N1256

6.5表达
...
3运算符和操作数的分组由语法指示。 74)除非后面指定(对于函数调用()&&||?:和逗号运算符),子表达式的评估顺序和副作用发生的顺序都是未指定的。

所以简短的回答是“不”;对于像E1[E2]这样的表达式,子表达式E1E2的评估顺序并不固定。

答案 2 :(得分:2)

我希望你只是好奇地问这个,并且取决于这种行为;

我附近没有C标准,但我不明白为什么你不能将操作分成两个单独的语句,添加一个显式序列点。您和其他人可能不记得将来正确的订单应该是什么,从而产生维护问题。

int * the_array = E1;
the_array[E2];

//or

int the_index = E2;
E1[the_index];

//is much clearer

答案 3 :(得分:2)

下标运算符的评估顺序为undefined。让我们举另一个没有混淆的例子。

问题:请考虑以下表达式:

f() + g() * h()

优先权非常明确;乘法胜过加法,如相应的解析树所示:

       +
    /     \
   /       \
  f()       *
  /          \
  /           \
 g()           h()

优先级表只告诉我们如何对术语进行分组,而不是它们的评估顺序。使订单可预测的唯一方法是引入C标准调用sequence points的内容。例如,步骤:

x = g();
x = x * h();
x = x + f();

产生与以前相同的优先级,但是以保证顺序g()h()f()调用函数。

因此,在您的示例中,您必须引入序列点以确保以所需顺序执行printf语句。