C中的数组下标[]列出的优先级高于前缀增量。
遵循以下简单程序:
#include <stdio.h>
int main()
{
char testArr[] = "asdfgh";
int a = 0;
printf("element is %c\n",testArr[++a]);
}
为什么要打印而不是? 我看东西的方式,[]应该先应用。 这意味着应该显示testArr的第一个元素0而不是元素1.
答案 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] )
因此,下标运算符(包括方括号++a
或testArr
中的子表达式首先进行求值,然后对一元运算符进行求值。
另一方面,如果要使用后缀增量,如
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标准,并没有提到有关多维数组下标的任何内容。