需要澄清指针增量

时间:2013-10-19 04:00:28

标签: c pointers

请帮助我理解以下代码的工作原理:

#include <stdio.h>

int main(){
    int a = 10;
    void *b = &a;
    int *p = b; 
    printf("%u",*p++);
    return 0;
}

我知道printf的输出是10,但我不太关注为什么* p ++是10

以下是我的步骤:

1)void *b = &a;存储指针b的地址

2)int *p = b;指针p现在指向与指针b相同的数据项

3)printf("%u",*p++);是我感到困惑的地方......指针p的取消引用是a,这是10 ...不是*p++基本上与10 + 1相同,这将是11?

6 个答案:

答案 0 :(得分:3)

*p++基本上是*(p++)。它会在p递增之前评估a的值,这是10的地址。然后取消引用它,其值为{{1}}。

答案 1 :(得分:2)

变量p是指向int(指向a)的指针

表达式* p取消引用指针,因此就像直接访问int一样。

指针p上的operator postfix ++优先于解除引用。因此* p ++递增指针p(对于int之后的内存中的任何垃圾)在计算表达式之后,解除引用仍然解析为a,这就是打印10的原因。但是在运行语句之后,p的值会改变。因此,如果你使用printf(“%u”,* p),可能在该语句之后你会得到一个尴尬的价值。

但是,如果执行++ * p,则表达式将在p指向的dereferenced int变量上计算为++运算。如果你想避免这样的麻烦,当不确定时,使用括号:

(*p)++
++(*p)

而且你确定你正在取消引用价值并采取行动。增加指针值是C和C ++等语言允许的非常危险的操作,所以尽量避免!

答案 2 :(得分:2)

表达式*p++中的后增量运算符适用于指针,而不是存储在该位置的值,因此在评估之后之前的结果永远不会是11。表达式*p++表示:取消引用p(获取它的值)然后将p增加一个位置。由于p指向int,因此递增它会将其向前移动sizeof(int)个字节。添加永远不适用于p指向的值,即10。

然而,表达式(* p)++是不同的。它取消引用p(获取其值),然后递增该内存位置中的值。表达式求值为原始值。所以在执行语句

之后
int c = (*p)++;

变量c等于10,而a等于11。

答案 3 :(得分:2)

*p++被解析为*(p++)p++评估为p然后递增p,因此在下次引用p之前不会看到更改。因此*p为10,*p++为10(但p现在指向&a+1),*++p是未定义的行为(因为*(&a+1)不是有效值) ,(*p)++为10,但a更改为11,++*p(或++(*p))为11(a}。

答案 4 :(得分:2)

为什么* p ++是10?

  

[C11:§6.5.2.4/ 2]:postfix ++运算符的结果是操作数的值。作为副作用,操作数对象的值会递增(即,将相应类型的值1添加到其中)。

以下声明

printf("%u",*p++);

相当于

printf("%u",*p); /* p points to 'a' and value of `a` is 10. Hence, 10 is printed */
p = p + 1;  

p的类型为 pointer-to-int 。因此,1缩放为sizeof (int)

因此,p现在指向int地址:p + sizeof (int)

答案 5 :(得分:1)

我只想加五美分 要通过指针增加值间接值,您可以使用++*ip(*ip)++。关于K&amp; R书中括号的一个很好的解释:

  

在最后一个例子中,括号是必要的   (*ip)++;没有他们,他们表达   将增加ip而不是它指向的内容,因为   像*和++这样的一元运算符从右到左关联。

在您的代码中,您得到10,因为printf将打印变量的原始值,并且只有在使用postfix ++运算符后才会增加1。