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
发生的衰退是一样的。我努力了,但还是不明白。你能帮我更好地理解它吗?谢谢!!