编译器将解释a[1]为一系列标记,而不是字符串:*({a {operator} + {integer} 1的整数位置}与*({integer} 1 {operator} + {a的整数位置)相同但与*({a {operator} + {operator} +}的整数位置)不同
—Dinah 2010年
不合逻辑的数组访问中对此有一个有趣的复合变化,在其中有char bar[]; int foo[];并foo[i][bar]用作表达式。
—乔纳森·勒夫勒
@EldritchConundrum,您为什么认为“编译器无法检查左部分是否为指针”?是的,它可以。这是真的,a[b]=*(a + b)对于任何给定a和b,但它是语言的设计者自由选择的+,为所有类型的定义交换。没有什么可以阻止他们i + p在允许的情况下禁止使用p + i。
—2014年
@Andrey一个人通常期望+是可交换的,所以也许真正的问题是选择使指针运算类似于算术运算,而不是设计单独的偏移运算符。
—Eldritch难题,2014年
Answers:
C标准将[]运算符定义如下:
a[b] == *(a + b)
因此a[5]将评估为:
*(a+5)
并且5[a]将计算为:
*(5+ a)
a是指向数组第一个元素的指针。a[5]是距,与相同的5个元素的值,从小学数学我们知道它们是相等的(加法是可交换的)。a*(a + 5)
我想知道它是否更像*((5 * sizeof(a))+ a)。很好的解释。
—约翰·麦金太尔
@Dinah:从C编译器的角度来看,您是对的。不需要sizeof,我提到的那些表达式是相同的。但是,在生成机器代码时,编译器将考虑sizeof。如果a是一个int数组,a[5]它将编译为类似mov eax, [ebx+20]的[ebx+5]
—格式,
@Dinah:A是一个地址,例如0x1230。如果a在32位int数组中,则a [0]处于0x1230,a [1]处于0x1234,a [2]处于0x1238 ... a [5]处于x1244等。如果我们将5加到0x1230,我们得到0x1235,这是错误的。
—James Curran
@ sr105:这是+运算符的