2012-08-31 58 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操作應用。

相關問題