Eri*_*ken 20 c arrays pointers unary-operator postfix-operator
今天,我偶然发现了一个谜语,这给我带来了新的惊喜。
我不认为下面的示例中的-1 [p]可以编译,但是可以。实际上,x最终为-3。
int x;
int array[] = {1, 2, 3};
int *p = &array[1];
x = -1[p]
Run Code Online (Sandbox Code Playgroud)
我在互联网上搜索了-1 [pointer]之类的东西,但找不到任何东西。好的,我承认很难输入正确的搜索查询。谁知道为什么-1 [p]编译而X变为-3?
小智 27
我就是做出这个“谜”的人(请参阅我的Twitter帖子)
所以!-1 [p]是怎么回事?
ISO C实际上将[]定义为对称的,其含义x[y]
与相同y[x]
,其中x和y均为表达式。
天真,我们可以跳到结论,-1[p]
因此p[-1]
等x = 1
,但是,实际上-1是适用于恒定的1元减运算符,和一元减比一个低优先级[]
因此,-1[p]
是-(p[1])
,得出-3。
这也可能导致看起来像这样的时髦片段:
sizeof(char)["abc"] /* yields 'b' */
sep*_*p2k 12
首先要弄清的是优先级。即[]
具有比一元运算符更高的优先级,因此-1[p]
等于-(1[p])
,而不是(-1)[p]
。因此,我们正在取反的结果1[p]
。
x[y]
等于*(x+y)
,等于,1[p]
等于*(1+p)
,等于*(p+1)
,等于p[1]
。
因此,我们将元素带到p
指向何处的位置,array
然后取元素的第三个元素(即3),然后取反,这样就得出了-3
。
Vla*_*cow 10
根据C标准(6.5.2后缀运算符),下标运算符的定义方式如下
postfix-expression [ expression ]
Run Code Online (Sandbox Code Playgroud)
因此,在方括号之前应有一个后缀表达式。
在此表达声明中
x = -1[p];
Run Code Online (Sandbox Code Playgroud)
使用了后缀表达式1
(同时是主表达式),后缀表达式1[p]
(即下标运算符)和一元运算符。-
请考虑到,当编译器将程序拆分为标记时,整数常量被视为本身没有负号。减号是一个单独的标记。
因此,该语句可以像
x = -( 1[p] );
Run Code Online (Sandbox Code Playgroud)
因为后缀表达式的优先级高于一元表达式。
首先考虑一下postfix子表达式 1[p]
根据C标准(6.5.2.1数组下标)
2后缀表达式后跟方括号[]是数组对象元素的下标名称。下标运算符[]的定义是E1 [E2]与(*((E1)+(E2)))相同。由于适用于二进制+运算符的转换规则,如果E1是一个数组对象(相当于一个指向数组对象初始元素的指针),而E2是一个整数,则E1 [E2]表示E1的第E2个元素E1(从零开始计数)。
因此,此子表达式的计算*( ( 1 ) + ( p ) )
方式与相同*( ( p ) + ( 1 ) ).
因此,以上陈述
x = -1[p];
Run Code Online (Sandbox Code Playgroud)
相当于
x = -p[1];
Run Code Online (Sandbox Code Playgroud)
并会产生-3
,因为p
由于该语句,指针指向数组的第二个元素
int *p = &array[1];
Run Code Online (Sandbox Code Playgroud)
然后该表达式p[1]
得出该数组第二个元素之后的元素的值。然后-
应用一元运算符。
这个
int array[] = {1, 2, 3};
Run Code Online (Sandbox Code Playgroud)
看起来像
array[0] array[1] array[2]
--------------------------
| 1 | 2 | 3 |
--------------------------
0x100 0x104 0x108 <-- lets assume 0x100 is base address of array
array
Run Code Online (Sandbox Code Playgroud)
接下来当你喜欢
int *p = &array[1];
Run Code Online (Sandbox Code Playgroud)
整数指针p
指向array[1]
ie的地址0x104
。看起来像
array[0] array[1] array[2]
--------------------------
| 1 | 2 | 3 |
--------------------------
0x100 0x104 0x108 <-- lets assume 0x100 is base address of array
|
p holds 0x104
Run Code Online (Sandbox Code Playgroud)
当你喜欢的时候
x = -1[p]
Run Code Online (Sandbox Code Playgroud)
-1[p]
相当于-(1[p])
即-(p[1])
。看起来像
-(p[1]) ==> -(*(p + 1*4)) /* p holds points to array[1] i.e 0x104 */
==> -(*(0x104 + 4))
==> -(*(0x108)) ==> value at 0x108 is 3
==> prints -3
Run Code Online (Sandbox Code Playgroud)