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

hxzsmxv2  于 2023-01-29  发布在  其他
关注(0)|答案(5)|浏览(116)
    • 此问题在此处已有答案**:

With arrays, why is it the case that a[5] == 5[a]?(20个答案)
三年前关闭了。
今天我无意中发现了一个让我大吃一惊的谜语。
我没想到下面例子中的-1 [p]会编译,但它编译成功了,事实上,x最终是-3。

int x;
    int array[] = {1, 2, 3};
    int *p = &array[1];
    x = -1[p];

我在互联网上搜索了类似-1 [pointer]的东西,但是什么也没找到。好吧,我承认输入正确的搜索查询很困难。谁知道为什么-1 [p]编译后X变成了-3?

b1payxdu

b1payxdu1#

我是制作这个“谜语”的人(请参见my Twitter post
那么,-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' */

cvxl0en2

cvxl0en22#

首先要弄清楚的是优先级,也就是说[]比一元运算符的优先级高,所以-1[p]等于-(1[p]),而不是(-1)[p],所以我们取1[p]的结果并求反。
x[y]等于*(x+y),所以1[p]等于*(1+p)*(1+p)等于*(p+1)*(p+1)等于p[1]
我们取p指向的第一个元素,也就是array的第三个元素,也就是3,然后取反,得到-3

jexiocij

jexiocij3#

根据C标准(6.5.2后缀运算符),下标运算符按以下方式定义

postfix-expression [ expression ]

因此,方括号前应有一个后缀表达式。
在此表达式语句中

x = -1[p];

使用了后缀表达式1(同时也是主表达式)、后缀表达式1[p](也就是下标运算符)和一元运算符-。考虑到当编译器将程序拆分为标记时,整数常量被认为是没有减号的标记本身。减号是单独的标记。
所以这个语句可以重写为

x = -( 1[p] );

因为后缀表达式比一元表达式具有更高的优先级。
我们首先考虑后缀子表达式1[p]
根据C标准(6.5.2.1数组下标)
2一个后缀表达式后面跟一个方括号[]中的表达式是数组对象的一个元素的下标指定。下标运算符[]的定义是E1[E2]等同于(*((E1)+(E2)))。由于应用于二元运算符+的转换规则,如果E1是数组对象(相当于指向数组对象初始元素的指针)且E2是整数,则E1[E2]指定E1的第E2个元素(从零开始计数)。
因此,此子表达式的计算结果类似于*( ( 1 ) + ( p ) ),并且与*( ( p ) + ( 1 ) ).相同
因此上述声明

x = -1[p];

相当于

x = -p[1];

并将生成-3,因为由于语句,指针p指向数组的第二个元素

int *p = &array[1];

然后表达式p[1]得出数组第二个元素之后的元素的值,然后应用一元运算符-

wecizke3

wecizke34#

这个

int array[] = {1, 2, 3};

看起来像

array[0]   array[1]  array[2]
 --------------------------
|     1   |    2    |   3  | 
 --------------------------
 0x100     0x104     0x108   <-- lets assume 0x100 is base address of array
array

下一次当你喜欢

int *p = &array[1];

整数指针p指向array[1]的地址,即0x104。如下所示

array[0]   array[1]  array[2]
 --------------------------
|     1   |    2    |   3  | 
 --------------------------
 0x100     0x104     0x108   <-- lets assume 0x100 is base address of array
             |
            p holds 0x104

当你喜欢的时候

x = -1[p]

-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
qv7cva1a

qv7cva1a5#

这里发生的事情真的很有趣。
p[n]表示*(p+n),这就是为什么您看到3,因为“p”指向数组[1],数组[1]的值为2,而-p[1]被解释为-(*(p+1)),它的值为-3。

相关问题