C++ 为什么在执行增量操作之前分配指针值

C++ 为什么在执行增量操作之前分配指针值,c++,c,pointers,C++,C,Pointers,为什么*p++首先将值赋给i,然后递增p指针,即使++递增后具有更高的优先级,并且关联性是从右向左的 int main() { int a[]={55,66,25,35,45}; int i; int *p=&a; printf("%u \n",p); i=*p++; printf(" %u %d",p,i); printf("\n %d",*p); return 0; } 4056 4060 55 66 在指针和数组

为什么
*p++
首先将值赋给
i
,然后递增
p
指针,即使
++
递增后具有更高的优先级,并且关联性是从右向左的

int main()
{
    int a[]={55,66,25,35,45};
    int i;
    int *p=&a;
    printf("%u \n",p);
    i=*p++;
    printf(" %u  %d",p,i);
    printf("\n %d",*p);

    return 0;
}
4056 4060 55 66
在指针和数组如何协同工作方面似乎存在一些误解

表达式
&a
是指向数组本身的指针,其类型为
int(*)[5]

您似乎希望得到指向第一个元素的指针,它将是
&a[0]
,或者是普通的
a
(因为它会衰减为指向第一个元素的指针):

它的工作并不是巧合,因为指向数组的指针恰好指向与第一个元素位置相同的地址。地址相同,但
&a
&a[0]
的类型不同。这种语义上的差异确实至关重要


关于
++
操作符的问题,这只是它的工作原理

后缀递增或递减运算符的结果是旧值。因此,当您执行
p++
操作时,您会在指针增加之前得到旧指针

如果我们采取

i = *p++;
它(稍微简化)相当于

int *temporary_old_p = p;
p = p + 1;
i = *temporary_old_p;

此外,指针的
“%u”
格式无效。要打印
void*
指针(确实需要正确的强制转换),您应该使用
%p”
格式说明符

格式说明符和参数类型不匹配会导致未定义的行为


关于
*(&a+1)
的问题,让我们绘制数组
a
在内存中的外观,用几个箭头来显示指针:

+------+------+------+------+------+------ | a[0] | a[1] | a[2] | a[3] | a[4] | .... +------+------+------+------+------+------ ^ ^ | | &a[0] | | | &a &a + 1 +------+------+------+------+------+------ |a[0]| a[1]| a[2]| a[3]| a[4]|。。。。 +------+------+------+------+------+------ ^ ^ | | &a[0]| | | &a&a+1 由于
&a
的类型是
int(*)[5]
,因此
&a+1
的类型也应该是
int(*)[5]

如果我们取消引用指针
&a
(如
*(&a)
),则得到实际数组
a
。数组,如
a
,衰减为指向其第一个元素
&a[0]
的指针。此指针指向与
&a
相同的位置(如上面的“图纸”所示)

如果我们将
&a
更改为
&a+1
,则在解引用中得到
*(&a+1)
。它是“第二个”数组(是否存在)。就像
*(&a)
是一个由五个
int
组成的数组一样,
*(&a+1)
也是如此。此数组衰减为指向其第一个元素
&(*(&a+1))[0]
的指针


或者认为
&a
等于
&a+0
。然后很容易看出
*(&a)
将等于
*(&a+0)
。我们知道
*(&a)
等于
a
,后者等于
&a[0]
,这也意味着
*(&a+0)
必须等于
&((&a+0))[0]
。这应该很容易看出
&(*(&a+1))[0]
可能是什么。

后缀
++
操作符的语义是表达式
p++
计算为
p
的当前值,并且作为副作用
p
增加。有效地,
i=*p++与相同

i = *p;
p++;
i = *(p + 1);
p++;
前缀
++
运算符的语义是表达式的计算结果为
p
的当前值加1,并且作为副作用
p
递增<代码>i=*++p实际上与

i = *p;
p++;
i = *(p + 1);
p++;

优先级不控制求值顺序-它只控制解析(哪些运算符与哪些操作数分组)

这段代码不应该编译。行
int*p=&a键入不正确。如果要打印指针,则需要格式说明符
%p
,否则将调用未定义的行为。在修复之前,任何事情都可能发生…
int*p=a为什么
&a
是指向int的指针
[5]
,而不是指向int的指针。请参阅:@gokulgoku:仅仅因为它运行时没有明显的错误并不意味着它是正确的。您应该至少收到几个警告。数组在需要时会自动衰减为指针:
int*p=a是您所需要的全部。获取
a
的地址会产生另一种指针类型:
int(*p)[5]=&a将是正确的…即使我将其更改为int*p=a;为什么我得到了相同的输出?@gokulgoku在答案中添加了一段解释。谢谢,我得到了它…我还有一个疑问,当我们有1到&a时,我们在数组结束后到达了地址。因此&a+1在数组a后给出了地址,但为什么*(&a+1)也给出了相同的地址address@gokulgoku这是因为
*(&a+1)
等于
(&a)[1]
,其类型为数组(五个
int
)。和任何数组一样,它衰减为指向其第一个元素的指针。这和
a
发生的衰退是一样的。我努力了,但还是不明白。你能帮我更好地理解它吗?谢谢!!