当p指向(整数)索引数组时,“-1 [p]”是什么?

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]得出该数组第二个元素之后的元素的值。然后-应用一元运算符。


Ach*_*hal 6

这个

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)