++ * p和* p ++之间的差异

时间:2020-03-11 09:43:56

标签: c

int *p,x=5;
p=&x;
x=++*p;
printf("%d\n",x);
x=*p++;
printf("%d\n",x);
x=++*p;
printf("%d",x);

尽管我知道前缀++首先增加值然后存储它,而后缀++首先存储值然后增加它。但是在最后一行中,为什么在printf语句中打印1?

3 个答案:

答案 0 :(得分:0)

  • x=++*p;将内容从5更改为6,然后将6存储在x中。 (前缀++和*具有相同的优先级,因此前缀运算符的运算符关联性从右到左起作用。)

  • x=*p++;意味着后缀++首先被评估,因为它具有更高的优先级。但是p的实际更改只会在执行整个表达式之后发生,因此*p中的值6将在发生之前存储在x中。

    请注意,++表示p现在指向实际有效内存位置之外的一个int。只要不取消引用变量,在C中都可以允许这种指向超出分配范围的第一项的特殊情况。

  • x=++*p;这里的指针被取消引用,这是不允许的,因此这是一个错误(与++无关)。这是不确定的行为,任何事情都可能发生。对您而言,这次恰好打印1。对我来说,这次打印的是8958。但是,由于它是未定义的行为错误,因此程序也可能崩溃或以其他随机方式启动。

请注意,在同一表达式中将++与其他运算符混合使用是不好的做法。 ++运算符非常危险,因为它们会引入书写的副作用,并且这种副作用可能无法与表达式的其余部分配合。

答案 1 :(得分:0)

伦丁有一个很好的,彻底的答案。我希望这不是题外话...

最后一条语句恰好是将指针递增为整数。如果将打印语句更改为此,您将看到p的增量。

    printf("%d, %p\n",x,p);

使用gcc,我得到以下输出:

6,0x7ffeee3a92a4
6,0x7ffeee3a92a8
-298151255,0x7ffeee3a92a9

在这里,您可以看到前两行的指针都增加了sizeof(int)(4字节)。但是,未定义的行为发生在最后一条语句中,在我的情况下,该语句打印出垃圾,因为它不再与4B对齐。在这种情况下,碰巧现在将指针视为一个int(因为它现在将值加1)。

答案 2 :(得分:0)

这里有一个更好的例子:

int main()
{
    int *p,x[4]={1,2,3,4};
    p=x;
    ++*p;
    printf("%2d %2d %2d %2d\n",x[0], x[1], x[2], x[3]);
    printf("p: %p x: %p\n", (void *)p, (void *)x);
    *p++;
    printf("%2d %2d %2d %2d\n",x[0], x[1], x[2], x[3]);
    printf("p: %p x: %p\n", (void *)p, (void *)x);
    ++*p;
    printf("%2d %2d %2d %2d\n",x[0], x[1], x[2], x[3]);
    printf("p: %p x: %p\n", (void *)p, (void *)x);
}
the output is
 2  2  3  4
p: 0x7ffc7ef56670 x: 0x7ffc7ef56670
 2  2  3  4
p: 0x7ffc7ef56674 x: 0x7ffc7ef56670
 2  3  3  4
p: 0x7ffc7ef56674 x: 0x7ffc7ef56670