int main(){
int array[] = [10,20,30,40,50] ;
printf("%d\n",-2[array -2]);
return 0 ;
}
è°èƒ½è§£é‡Š-2 [array-2]的工作方å¼ï¼Œä¸ºä»€ä¹ˆåœ¨è¿™é‡Œä½¿ç”¨[]? 这是我分é…ä¸çš„一个问题,它给出的输出为“ -10â€ï¼Œä½†æˆ‘ä¸æ˜Žç™½ä¸ºä»€ä¹ˆï¼Ÿ
ç”案 0 :(得分:5)
从技术上讲,这会调用未定义的行为。引用C11
,第6.5.6ç«
 Â如果两个指针都   æ“作数和结果指å‘åŒä¸€æ•°ç»„å¯¹è±¡çš„å…ƒç´ ï¼Œæˆ–è€…æŒ‡å‘最åŽä¸€ä¸ªæ•°ç»„çš„å…ƒç´ Â Â æ•°ç»„å¯¹è±¡çš„å…ƒç´ ï¼Œæ±‚å€¼ä¸åº”产生溢出;å¦åˆ™ï¼Œ   行为是ä¸ç¡®å®šçš„。 [....]
å› æ¤ï¼Œ(array-2)
是未定义的行为。
但是,大多数编译器将读å–索引,并且å¯èƒ½èƒ½å¤Ÿä½¿+2
和-2
ç´¢å¼•æ— æ•ˆï¼Œ[2[a]
与a[2]
相åŒï¼Œä¸Ž*(a+2)
相åŒï¼Œå› æ¤2[a-2]
是*((2)+(a-2))
],并且仅考虑è¦æ±‚值的其余表达å¼ï¼Œå³*(a)
或a[0]
。>
然åŽï¼Œæ£€æŸ¥operator precedence
-2[array -2]
实际上与-(array[0])
相åŒã€‚å› æ¤ï¼Œç»“果是值array[0]
和-
ved。
ç”案 1 :(得分:3)
这是一个ä¸å¹¸çš„æ•™å¦ç¤ºä¾‹ï¼Œå› 为这æ„味ç€å¯ä»¥åšä¸€äº›é€šå¸¸åœ¨å®žè·µä¸ä¸æ£ç¡®çš„事情。
技术上æ£ç¡®çš„ç”案是该程åºå…·æœ‰æœªå®šä¹‰çš„è¡Œä¸ºï¼Œå› æ¤ä»»ä½•ç»“果都是å¯èƒ½çš„,包括打å°-10,打å°ä¸åŒçš„æ•°å—,打å°å®Œå…¨ä¸åŒæˆ–æ ¹æœ¬ä¸æ‰“å°çš„ä¸œè¥¿ï¼Œæ— æ³•è¿è¡Œï¼Œå´©æºƒå’Œ/或执行æŸäº›æ“ä½œå®Œå…¨æ— å…³ã€‚
未定义的行为æ¥è‡ªè¯„ä¼°å表达å¼array -2
的结果。 array
从其数组类型衰å‡ä¸ºæŒ‡å‘ç¬¬ä¸€ä¸ªå…ƒç´ çš„æŒ‡é’ˆã€‚ array -2
会指å‘ä½äºŽæ¤ä½ç½®ä¹‹å‰ä¸¤ä¸ªä½ç½®çš„å…ƒç´ ï¼Œä½†æ˜¯æ²¡æœ‰è¿™æ ·çš„å…ƒç´ ï¼ˆå¹¶ä¸”è¿™ä¸æ˜¯â€œå•ç«¯ç»“æŸâ€çš„ç‰¹æ®Šè§„åˆ™ï¼‰ï¼Œå› æ¤æ— 论如何评估,这都是一个问题它出现的上下文。
(C11 6.5.6 / 8说)
 Â当将整数类型的表达å¼æ·»åŠ 到指针或从指针ä¸å‡åŽ»æ—¶ï¼Œ....如果指针æ“作数和结果都指å‘åŒä¸€æ•°ç»„å¯¹è±¡çš„å…ƒç´ ï¼Œæˆ–è€…æŒ‡å‘数组对象的最åŽä¸€ä¸ªå…ƒç´ ,评估ä¸ä¼šäº§ç”Ÿæº¢å‡ºï¼›å¦åˆ™ï¼Œè¡Œä¸ºæ˜¯ä¸ç¡®å®šçš„。
现在,教师å¯èƒ½æ£åœ¨å¯»æ‰¾çš„技术上ä¸æ£ç¡®çš„ç”案是大多数实现ä¸å®žé™…å‘生的事情:
å³ä½¿array -2
ä¸åœ¨å®žé™…数组之外,它也会求值为数组数æ®èµ·å§‹åœ°å€å‰2*sizeof(int)
个å—节的æŸä¸ªåœ°å€ã€‚å–消引用该地å€æ˜¯æ— æ•ˆçš„ï¼Œå› ä¸ºæˆ‘ä»¬ä¸çŸ¥é“那里确实有int
,但我们ä¸ä¼šã€‚
查看较大的表达å¼-2[array -2]
,[]
è¿ç®—符比一元-
è¿ç®—ç¬¦å…·æœ‰æ›´é«˜çš„ä¼˜å…ˆçº§ï¼Œå› æ¤å®ƒè¡¨ç¤º-(2[array -2])
而ä¸æ˜¯(-2)[array -2]
。 A[B]
的定义与*((A)+(B))
相åŒã€‚通常将A
用作指针值,将B
用作整数值,但是åƒæˆ‘们在æ¤å¤„所åšçš„é‚£æ ·ï¼Œä»¥ç›¸åçš„æ–¹å¼ä½¿ç”¨å®ƒä»¬ä¹Ÿæ˜¯åˆæ³•çš„。所以这些是ç‰æ•ˆçš„:
-2[array -2]
-(2[array -2])
-(*(2 + (array - 2)))
-(*(array))
最åŽä¸€æ¥çš„è¡Œä¸ºä¸Žæˆ‘ä»¬é¢„æœŸçš„ä¸€æ ·ï¼šå°†ä¸¤ä¸ªå€¼æ·»åŠ åˆ°array - 2
的地å€å€¼ä¹‹åŽæ˜¯2*sizeof(int)
个å—èŠ‚ï¼Œè¿™ä½¿æˆ‘ä»¬è¿”å›žåˆ°ç¬¬ä¸€ä¸ªæ•°ç»„å…ƒç´ çš„åœ°å€ã€‚å› æ¤*(array)
å–消引用该地å€ï¼Œç»™å‡º10,而-(*(array))
å–消该值,给出-10。程åºæ‰“å°-10。
å³ä½¿æ‚¨åœ¨ç³»ç»Ÿå’Œç¼–译器上看到它“起作用â€ï¼Œä¹Ÿæ°¸è¿œä¸è¦æŒ‡æœ›è¿™ç§äº‹æƒ…。由于该è¯è¨€æ— 法ä¿è¯å°†è¦å‘ç”Ÿçš„ä¸€åˆ‡ï¼Œå› æ¤ï¼Œå¦‚果您进行了似乎ä¸åº”该进行的微å°æ›´æ”¹ï¼Œæˆ–者在其他系统,ä¸åŒçš„编译器,相åŒç‰ˆæœ¬çš„åŒä¸€ç‰ˆæœ¬æˆ–使用åŒä¸€ç³»ç»Ÿå’Œå¦ä¸€å¤©çš„编译器。
ç”案 2 :(得分:1)
以下是-2[array-2]
的评估方å¼ï¼š
首先,请注æ„,-2[array-2]
被解æžä¸º- (2[array-2])
ã€‚ä¸‹æ ‡è¿ç®—符[...]
的优先级高于一元-
è¿ç®—符。我们ç»å¸¸å°†è¯¸å¦‚-2
之类的常é‡è§†ä¸ºå•ä¸ªæ•°å—,但实际上它是应用于-
çš„{​​{1}}è¿ç®—符。
在2
ä¸ï¼Œarray-2
自动转æ¢ä¸ºæŒ‡å‘å…¶ç¬¬ä¸€ä¸ªå…ƒç´ çš„æŒ‡é’ˆï¼Œå› æ¤å®ƒæŒ‡å‘array
。
然åŽarray[0]
å°è¯•è®¡ç®—指å‘数组ä¸ç¬¬ä¸€ä¸ªå…ƒç´ 之å‰çš„ä¸¤ä¸ªå…ƒç´ çš„æŒ‡é’ˆã€‚ Cæ ‡å‡†æœªå®šä¹‰æœ€ç»ˆçš„è¡Œä¸ºï¼Œå› ä¸ºC 2018 6.5.6 8表示仅定义了指å‘数组æˆå‘˜å’Œæ•°ç»„末尾的算法。
仅出于说明目的,å‡è®¾æˆ‘们使用的C实现通过定义指针使用平é¢åœ°å€ç©ºé—´å¹¶å…许任æ„指针算术æ¥æ‰©å±•Cæ ‡å‡†ã€‚ç„¶åŽarray-2
指å‘数组å‰é¢çš„ä¸¤ä¸ªå…ƒç´ ã€‚
然åŽarray-2
使用Cæ ‡å‡†å°†2[array-2]
定义为E1[E2]
çš„äº‹å®žã€‚ä¹Ÿå°±æ˜¯è¯´ï¼Œä¸‹æ ‡è¿ç®—ç¬¦æ˜¯é€šè¿‡å°†è¿™ä¸¤ä»¶äº‹ç›¸åŠ å¹¶åº”ç”¨*((E1)+(E2))
æ¥å®žçŽ°çš„ã€‚å› æ¤ï¼Œå“ªä¸ªè¡¨è¾¾å¼ä¸º*
和哪个表达å¼ä¸ºE1
并ä¸é‡è¦ã€‚ E2
与E1+E2
相åŒã€‚å› æ¤E2+E1
是2[array-2]
ã€‚åŠ 2将指针从数组之å‰çš„ä¸¤ä¸ªå…ƒç´ ç§»å›žæ•°ç»„çš„å¼€å¤´ã€‚ç„¶åŽåº”用*(2 + (array-2))
会在该ä½ç½®10äº§ç”Ÿå…ƒç´ ã€‚
最åŽï¼Œåº”用*
得到-10。 (回想一下,åªæœ‰é€šè¿‡æˆ‘们的å‡è®¾ï¼Œå³C实现支æŒå¹³é¢åœ°å€ç©ºé—´æ‰èƒ½å¾—出æ¤ç»“论。您ä¸èƒ½åœ¨é€šç”¨C代ç ä¸ä½¿ç”¨å®ƒã€‚)
ç”案 3 :(得分:0)
æ¤ä»£ç 调用未定义的行为,并且å¯ä»¥æ‰“å°ä»»ä½•å†…容,包括-10
。
C17 6.5.2.1æ•°ç»„ä¸‹æ ‡çŠ¶æ€ï¼š
 Âä¸‹æ ‡è¿ç®—符[]的定义是
E1[E2]
与(*((E1)+(E2)))
相åŒ
å«ä¹‰array[n]
ç‰æ•ˆäºŽ*((array) + (n))
ï¼Œè¿™å°±æ˜¯ç¼–è¯‘å™¨è¯„ä¼°ä¸‹æ ‡çš„æ–¹å¼ã€‚这使我们能够åƒn[array]
é‚£æ ·ç¼–å†™array[n]
è¿™æ ·çš„æ„šè ¢çš„æ··æ·†ï¼Œç‰åŒäºŽ*((n) + (array))
ã€‚å› ä¸º*((array) + (n))
ç‰æ•ˆäºŽ-2[array -2]
。如æ¤å¤„所述:
With arrays, why is it the case that a[5] == 5[a]?
专门查看表达å¼[array -2]
:
[array - 2]
和[]
自然是ç‰æ•ˆçš„。在这ç§æƒ…况下,å‰è€…åªæ˜¯è‰çŽ‡çš„æ ·å¼ï¼Œç›®çš„是为了混淆代ç 。-*( (2) + (array - 2) )
。 -
2
ä¸æ˜¯æ•´æ•°å¸¸é‡-
的一部分。 Cä¸æ”¯æŒè´Ÿæ•´æ•°å¸¸é‡ 1),[]
实际上是一元å‡è¿ç®—符。 -2[
ä½Žï¼Œå› æ¤[
ä¸çš„2会“绑定â€åˆ°(array - 2)
ã€‚æ ¹æ®C17 6.5.6 / 8:对å表达å¼(2) + (array - 2)
进行å•ç‹¬è¯„估并调用未定义的行为:
 Â将具有整数类型的表达å¼æ·»åŠ 到指针或从指针ä¸å‡åŽ»æ—¶ï¼Œ   结果具有指针æ“作数的类型。 //-如果指针æ“作数和结果都指å‘åŒä¸€æ•°ç»„å¯¹è±¡çš„å…ƒç´ ï¼Œæˆ–è€…æŒ‡å‘数组对象的最åŽä¸€ä¸ªå…ƒç´ ,则求值ä¸åº”产生溢出;å¦åˆ™ï¼Œè¡Œä¸ºæ˜¯ä¸ç¡®å®šçš„。
推测而言,未定义行为的一ç§æ½œåœ¨å½¢å¼å¯èƒ½æ˜¯ç¼–译器决定将整个表达å¼array
替æ¢ä¸º-*array
,在这ç§æƒ…况下,整个表达å¼æœ€ç»ˆå°†ä»¥{{1 }}并打å°-10
。
没有ä¿è¯ï¼Œå› æ¤ä»£ç 是错误的。如果为您分é…了解释代ç 为何打å°-10
的作业,则您的è€å¸ˆæ— 能。将混淆作为Cè¯è¨€ç ”ç©¶çš„ä¸€éƒ¨åˆ†è¿›è¡Œç ”ç©¶ä¸ä»…æ¯«æ— æ„义/有害,而且ä¾èµ–未定义的行为或期望其产生一定的结果也是有害的。
1) C更支æŒè´Ÿçš„整数常é‡è¡¨è¾¾å¼ã€‚ -2
是整数常é‡è¡¨è¾¾å¼ï¼Œå…¶ä¸2
是类型int
的整数常é‡ã€‚