为啥在执行递增操作之前分配指针值
Posted
技术标签:
【中文标题】为啥在执行递增操作之前分配指针值【英文标题】:why a pointer value is assigned before the increment operation is performed为什么在执行递增操作之前分配指针值 【发布时间】:2019-06-05 18:58:28 【问题描述】:为什么*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
【问题讨论】:
该代码不应该编译。int *p=&a;
行输入不正确。
如果你想打印一个指针,你需要格式说明符%p
,否则你会调用未定义的行为。在修复之前,任何事情都可能发生...
int *p=a;
为什么? &a
是 pointer-to-int [5]
,而不是 pointer-to-int。见:C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)
@gokulgoku:仅仅因为它运行时没有明显错误并不意味着它是正确的。你应该至少得到几个警告。
数组在需要时会自动衰减为指针:int* p = a;
就是您所需要的。取a
的地址会导致另一种指针类型:int(*p)[5] = &a;
将是正确的...
【参考方案1】:
后缀++
运算符的语义是表达式p++
计算为p
的当前 值,并且作为副作用 @987654324 @ 递增。实际上,i = *p++;
与
i = *p;
p++;
前缀 ++
运算符的语义是表达式计算为p
的当前值加一,并作为副作用p
递增。 i = *++p;
实际上与
i = *(p + 1);
p++;
优先级不控制评估顺序 - 它只控制解析(哪些运算符与哪些操作数分组)。
【讨论】:
【参考方案2】:在指针和数组如何协同工作方面似乎存在一些误解。
表达式&a
是指向数组本身的指针,类型为int (*)[5]
。
您似乎期望获得指向第一个元素的指针,即&a[0]
,或普通的a
(因为它衰减为指向数组第一个元素的指针):
int *p = a;
它的工作并不是巧合,因为指向数组的指针恰好指向与第一个元素的位置相同的地址。地址相同,但&a
和&a[0]
的类型不同。这种语义差异确实至关重要。
关于++
操作符的问题,简单来说就是它的工作原理。
后缀增减运算符的结果是old值。因此,当您执行 p++
时,您会在增加之前获得 old 指针。
如果我们采取
i = *p++;
它(有点简化)相当于
int *temporary_old_p = p;
p = p + 1;
i = *temporary_old_p;
此外,指针的"%u"
格式无效。要打印void *
指针(确实需要正确的转换),您应该使用"%p"
格式说明符。
格式说明符和参数类型不匹配会导致未定义的行为。
关于*(&a + 1)
的问题,让我们画出数组a
在内存中的样子,用几个箭头表示指针:
既然&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]
可能是什么。
【讨论】:
即使我把它改成 int *p=a;为什么我得到相同的输出? @gokulgoku 在答案中添加了一段解释它。 谢谢我明白了...我还有一个疑问,当我们有 1 到 &a 时,我们在数组结束后到达地址 ..so &a+1 在数组 a 之后给出了一个地址,但为什么*(&a+1) 也给出相同的地址 @gokulgoku 那是因为*(&a + 1)
等于(&a)[1]
,并且它的类型是一个数组(五个int
)。并且与任何数组一样,它衰减 为指向其第一个元素的指针。这与 a
发生的衰减相同。
好吧,我努力了,但我无法理解它,你能帮我更好地理解它吗...谢谢!!以上是关于为啥在执行递增操作之前分配指针值的主要内容,如果未能解决你的问题,请参考以下文章