C运算符优先级 - 数组下标和前缀增量

时间:2017-08-30 22:03:34

标签: c expression

C中的数组下标[]列出的优先级高于前缀增量。

遵循以下简单程序:

#include <stdio.h>
int main()
{
   char testArr[] = "asdfgh";
   int a = 0; 
   printf("element is %c\n",testArr[++a]);
}

为什么要打印而不是? 我看东西的方式,[]应该先应用。 这意味着应该显示testArr的第一个元素0而不是元素1.

5 个答案:

答案 0 :(得分:3)

下标运算符的定义方式如下

postfix-expression [ expression ]

因此,为了应用下标运算符,编译器应计算方括号中的表达式(以及后缀表达式)以获取表达式的值。

来自C标准(6.5.2.1数组下标)

  

2后缀表达式后跟方括号[]中的表达式   是数组对象元素的下标。的的   下标运算符[]的定义是E1 [E2]与...相同   (*((E1)+(E2)))即可。由于适用于的转换规则   binary +运算符,如果E1是数组对象(等效于指针   到数组对象的初始元素),E2是一个整数,   E1 [E2]表示E1的第E2个元素(从零开始计数)。

为了更清楚地考虑一个简单的代码片段

int i = 0;
int j = 1;

printf("element is %c\n",testArr[i + j]);

编译器如何在不计算表达式i + j

的情况下确定索引

这就是下标运算符由两个子表达式组成,这两个子表达式被计算得到它们的值。

如果考虑以下表达式,您的问题是否合理

++testArr[++a]

甚至以下表达式

++a[testArr]

在这种情况下,由于运算符优先级,第一个表达式等同于

++( testArr[++a] )

,第二个相当于

++( a[testArr] )

因此,下标运算符(包括方括号++atestArr中的子表达式首先进行求值,然后对一元运算符进行求值。

另一方面,如果要使用后缀增量,如

a++[testArr]

然后表达式等同于

( a++[testArr] )

就是它只是下标运算符,它遵循自己的定义形式

        a++        [  testArr   ]    
postfix-expression [ expression ]

答案 1 :(得分:1)

写作时

testArr[++a]

C将查看由表达式++a的值给出的数组中的索引。无论[]++之间的运算符优先级如何,表达式++a的值都比表达式初始计算之前的值a大一个,这就是为什么您在索引1处看到的字符而不是索引0处的字符。

答案 2 :(得分:1)

用简单的英语: [a ++] - 意味着[a + 1]操作将在所有其他操作之后完成, [++ a] - 表示[a + 1]操作将在所有其他操作之前完成。

答案 3 :(得分:0)

表达式可以包含多个操作及其操作数。通过使用括号,可以定义这些操作应执行的顺序。如果没有通过括号定义的顺序,则运算符优先级定义操作的顺序。

在您的情况下,++a[]操作数的子表达式,因此无论您在[]内放置什么,都会在评估之前对其进行评估[]操作数。

答案 4 :(得分:0)

因此,从Vlad发布的内容来看,似乎编译器会对表达式求值: testArr [++ a] as *((testArr)+(++ a))

但是,对于多维数组,以下程序打印2:

#include<stdio.h>

int main()
{
int a[3][3]={0,1,2,3,4,5,6,7,8};
int index=0;
printf("element is %d\n",a[index++][++index]);
}

如果有人能够解释这一点,那么使用C标准会更好。 我已经看过C标准,并没有提到有关多维数组下标的任何内容。

相关问题