2012-08-31 57 views
46

考虑:为什么* p ++与* p + = 1不同?

void foo1(char **p) { *p++; } 
void foo2(char **p) { *p += 1; } 

char *s = "abcd"; 
char *a = s; 
foo1(&a); 
printf("%s", a); //abcd 

,但如果我用foo2()代替:

char *a = s; 
foo2(&a); 
printf("%s", a); //bcd 

有人能解释一下吗?

+22

由于'* p ++'与'*(p ++)' –

+5

[运算符优先级](http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence)相同 – chris

+3

也尝试'void foo3(char ** p){(* p)++; }' –

回答

95

关键是+=++运算符的优先级。该++具有比+=一个更高的优先级(事实上,赋值运算符在C所述第二优先级最低),所以操作

*p++ 

意味着取消引用指针,然后通过递增1指针本身(如通常根据指针算术规则,它不一定是一个字节,而是关于结果地址的sizeof(*p))。在另一方面,

*p += 1 

手段增加指向指针一个值(什么也不做与指针本身)。

+8

你做了这么好的解释它的工作,但你可以请添加一个细节* P ++增加指针本身1“单位”,所以一个字符指针可能会增加一个,而int指针可能会增加4等,这取决于具体实现。 –

+3

@EdwinBuck:我没有看到相关性,这只是正常的指针算术,而不是问题的焦点。 – GManNickG

+5

@EdwinBuck无论指针是int还是char,当你增加它时,它都会增加1。由于指针的大小,表示该指针的实际地址可能会改变多个字节。 –

29

优先顺序。后缀++绑定比前缀*更紧密,因此它会增加p+=位于优先级列表的低端,以及普通的赋值运算符,所以它将*p加1。

0

前缀++和*的优先级相同。两者的关联性是从右至左的。 postfix ++的优先级高于*和prefix ++。 postfix ++的关联性从左到右。

0

让我们先从*p += 1

我会尝试从一个有点不同的角度回答这个...第1步让我们看看运营商和操作数:在这种情况下,它是一个操作数(指针p ),并且我们有两个运算符,在这种情况下,*用于取消引用,+ = 1用于增量。它具有较高的优先级*步骤2具有更高的优先级高于+ =


*P++ 这一个是有点麻烦...甚至恶 我们再次有一个操作数(P指针)和两个操作员,只有现在的*取消引用和++后增量具有相同的优先级。 (在某些表中,++中的帖子具有更高的优先级。)

第1步让我们看看运算符和操作数:在这种情况下,它是操作数,并且您有两个运算符,在这种情况下为* for取消引用和++进行增量。步骤2具有更高的优先级? ++比*有更高的优先级注意:即使它们具有相同的优先级,它们也会从右到左关联,再次,++在* 步骤3(棘手的部分...)其中是++?它是在操作数的右侧,这意味着POST递增在这种情况下,编译器采取'心理注释'来执行增量AFTER它与所有其他操作符一起完成... 什么是意味着?这意味着它只会将增量作为下一个“最后一步”的最后一步;所以它将与所有在同一行上的其他操作符一起完成 注意:如果它是* ++ p,那么它将在同一行上的任何其他操作符之前执行,因此在这种情况下,它等同于取两个处理器的寄存器,其中一个将保存解除引用的* p的值,另一个将保存递增的p ++的值,原因在这种情况下有两个,即POST活动...这就是在这个位置情况很棘手,看起来像是一个矛盾。我们可以期望++优先于*,它只是表示它只会在所有其他操作数之后应用,在下一个'之前'被应用。令牌...

就像我说的,棘手的部分是任何在操作数右边的增量都将被放在一边,并且在它移动到下一行之前将作为LAST操作应用。

相关问题