Where can I put an array subscript?

5

可能是重复问题:
在C语言中,为什么a[5]和5[a]相等?

这个问题 询问为什么

a[5] == 5[a]

除了一个方面外,所有方面都得到了回答...

首先,为什么允许在整数后面放置数组下标?其次,为什么不能写类似于

[a]5

或者

[5]a

还是将[]放在其他奇怪的地方?

换句话说,数组索引运算符允许的定义是什么?

编辑I:起初,我收到的引用标准的答案有点难以理解。但在回答者的帮助下,我现在明白了。指针或整数之后可以使用数组下标(方括号)。如果跟在指针后面,方括号内必须是一个整数。如果跟在整数后面,方括号内必须是一个指针。

我接受了得票较少的答案,因为他在让我理解标准引用时做了更多的手把手教学。但是严格引用标准的答案也是正确的。只是一开始理解起来比较困难。

编辑II:我不认为我的问题是重复的。我的问题是关于数组下标运算符允许的语法。它被引用标准的引用所回答,而这些引用从未出现在我被认为是重复的问题中。它是相似的,但并不是重复的。


1
因为C标准明确指出,E1[E2]*(E1+E2)是相同的,并且“+”是可交换的运算符。 - Alexey Frunze
1
那个问题回答了你的问题:“换句话说,在C编程语言(又名:K&R)中,数组索引运算符允许的定义是什么?” - m0skit0
@DanielFischer:完全正确,但标准是基于K&R的。 - m0skit0
@AlexeyFrunze 谢谢。那么,非整数类型不能在方括号后面跟随。那结构体呢?我猜我正在寻找方括号允许的定义位置。 - John Fitzpatrick
那样做没有什么作用。你也应该加上[E1]E2 - Alexey Frunze
显示剩余16条评论
3个回答

7
C11标准中的后缀表达式语法:
postfix-expression:
    primary-expression
    postfix-expression [ expression ]
    postfix-expression ( argument-expression-listopt )
    postfix-expression . identifier
    postfix-expression -> identifier
    postfix-expression ++
    postfix-expression --
    ( type-name ) { initializer-list }
    ( type-name ) { initializer-list , }

C11标准中的主要表达式语法:

primary-expression:
    identifier
    constant
    string-literal
    ( expression )
    generic-selection

等等。5是一个整数常量,所以5[a]匹配这个:

postfix-expression [ expression ]

希望这就是您所指的内容。
编辑:我忘了提到这一点,但其他评论已经提到:
其中一个表达式应具有“完整对象类型的指针”,另一个表达式应具有整数类型,并且结果具有“类型”类型。
需要“整数类型”以禁止无意义的浮点常量下标。

是的,感谢你和ouah,现在我明白我需要掌握后缀表达式的概念了。我要去学习了... - John Fitzpatrick
我现在必须取消您的答案,因为我无法看出为什么7.3[5]不是有效表达式,而您引用的语法中没有说明。7.5是一个常量,因此是一个基本表达式。那么标准中说什么不能跟在方括号后面呢? - John Fitzpatrick
我写的,这是标准中的最后一句话。不仅有语法,标准中还有“约束条件”。正如我所写:“其中一个表达式应具有'to complete object type'指针类型,另一个表达式应具有整数类型”;7.2既不是整数也不是指针,它是浮点常量,因此对于数组下标运算符来说不是有效的后缀表达式。 约束条件是“限制,无论是语法还是语义,都必须解释语言元素的表述方式”。 - effeffe
好的,是的,现在我明白了。我有点慢。E1和E2必须是指针和整数,顺序无所谓。感谢您的耐心。 - John Fitzpatrick

6

这里有 C 标准中数组下标运算符的定义:

(C99, 6.5.2.1p2) "用方括号 [] 将后缀表达式和一个表达式组合在一起,可以表示数组对象的元素。下标运算符 [] 的定义是 E1[E2] 等同于 (*((E1)+(E2)))。"

关于 E1E2 允许的类型:

(C99, 6.5.2.1p1) "其中一个表达式必须是“指向对象类型”的指针,另一个表达式必须是整数类型,结果的类型为“type”."


但是这并没有说明 [E1]E2 也是有效的,这才是实际问题。 - m0skit0
1
@m0skit0:由于E1和E2是自由变量,它们是可互换的。 - Dietrich Epp
@m0skit0,楼主没有问关于[E1]E2的问题! - Alexey Frunze
表达式是可以互换的,但符号不行。@AlexeyFrunze:“换句话说,数组索引运算符允许的位置的定义是什么?” - m0skit0
@m0skit0,C99的6.5.2c1规范中提到的后缀表达式[表达式]怎么样? - Alexey Frunze

2

a[5]的翻译是*(a+5)。加法是可交换的,所以a+5 = 5+a,这可以再次翻译为5[a]。我同意这是一个相当无用的功能,但是,为什么不呢?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接