繁体   English   中英

下标运算符的评估顺序

[英]Evaluation Order of Subscript Operator

在数组的情况下是否存在用于评估表达式的任何顺序。 如果表达式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编译它。

谢谢。

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

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

N1256

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

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

我希望你只是好奇地问这个问题而不是依赖于这种行为;

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

int * the_array = E1;
the_array[E2];

//or

int the_index = E2;
E1[the_index];

//is much clearer

下标运算符的评估顺序未定义 让我们举一个不那么混淆的例子。

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

f() + g() * h()

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM