在数组访问/下标中反转操作数的原因

use*_*234 8 c arrays

在C中,可以反转数组下标的操作数,但仍然可以获得相同的结果.例如a[b] == b[a].这是因为(根据 C11草案N1570,§6.5.2.1/ 2)a[b]是相同的(*((a)+(b))),并且+是可交换的.有关更多信息,请参阅此问题.

是否有一个场景(在C中,没有运算符重载),交换运算[]符的操作数不会在运行时产生相同的值?那么,是否存在一个ab哪个a[b] != b[a]?(假设程序编译并且a[b] == a[b])

Joh*_*ger 5

您似乎主要通过重申“为什么”与“a[b]含义相同”来回答了自己的问题b[a]。该解释是正确的,并且直接建立在标准的基础上。主要的警告是 和a必须b具有类型和值,以便评估a[b]完全定义了行为。只要是这种情况,两个表达式的计算结果就一定是相同的。否则,C 对于这两个表达式的计算结果是否相同没有任何说明。

稍微不同的策略是, ifab被允许表示比变量名和常量更复杂的表达式,那么可以选择它们,使得评估整个条件表达式(a)[b] == (b)[a]具有未定义的行为,即使评估左侧和右侧子表达式单独具有定义的行为。例如,

char array[2] = "a";
int index = 0;
// undefined:
_Bool condition = array[index++] == (index++)[array];
Run Code Online (Sandbox Code Playgroud)

但总的来说,无论和(a)[b] != (b)[a]的类型、形式或值如何,C 都不会将表达式定义为 true 。ab


cad*_*luk 3

好吧,如果你将此视为一个有效的反例:

int *i;
*i[i]; // does not compile
i[*i]; // does compile
Run Code Online (Sandbox Code Playgroud)

原因是下标运算符的优先级高于间接运算符,因此*i[i]相当于*(i[i]),这是无效的,因为下标运算符不能接受两种指针类型。


当然,请注意,这些示例在实际执行时会产生未定义的行为。它只是应该回答OP的问题。

  • 您可以通过将第一行更改为“int *i = &(int){0};”来轻松定义示例。 (2认同)
  • 不管怎样,都赞成,但在`*i[i]`中,`*i`不是下标的操作数,而在`i[*i]`中它是。 (2认同)