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

时间:2019-06-05 18:58:28

标签: 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

2 个答案:

答案 0 :(得分:8)

后缀++运算符的语义是表达式p++的计算结果为p current 值,并且是的副作用 p递增。实际上,i = *p++;

相同
i = *p;
p++;

前缀 ++的语义是表达式的求值为p 加一的当前值,并且效果p增加。 i = *++p;实际上与

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

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

答案 1 :(得分:4)

在指针和数组如何协同工作方面似乎存在一些误解。

表达式&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[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]可能是什么。