2012-06-22 154 views
0
#include<stdio.h> 
int main() 
{ 
    char *s[] = { "knowledge","is","power"}; 
    char **p; 
    p = s; 
    printf("%s ", ++*p); 
    printf("%s ", *p++); 
    printf("%s ", ++*p); 

    return 0; 
} 

輸出:字符串指針

nowledge nowledge小號

請解釋輸出從2 printf() statement.I特別輸出認爲,因爲++*具有相同的優先級,因此在*p++p應先遞增,然後使用*(一元運算符從右到左的關聯性)。

+0

作爲參考:在情況下,它不明顯,**這代碼改變S [1]'**如果陣列正在傳遞給你'S [0]'和'那會是一個討厭的副作用;你會讓這些指針基本上不可用。這就是爲什麼我討厭把解引用和增量結合起來的原因之一 - 做錯事很容易。 :P – cHao

+0

這真的是功課嗎?他們沒有更好的東西供你學習?或者這是否意味着一個不好的例子,例如,你學習*而不是*做這樣的事情? –

回答

3

根據C++ Operator Precedence

  1. 「*」 具有相同的優先級前綴 「++」,但必須avaluated 分辯向左

    printf(「%s」,++ * p);

所以第一*p進行評估,然後++(*p),導致第一個字符串中的第二個字符。

  1. 「*」 具有優先級比後綴 「++」。

    printf(「%s」,* p ++);

所以第一p遞增,它是一個後遞增。從操作返回的值是原始值。這樣,*對原始指針進行操作,該指針指向第一個字符串上的第二個字符。

請注意,這次,++正在運行p以上,而不是*p

  1. 由於「2」,p指向第二個字符串。當您做++*p時,您現在指向第二個字符串(「s」)的第二個字符。當您再次使用預增值時,傳遞至printf的值已更改。

    printf(「%s」,++ * p);

如果你做一點點改變我可能會更清晰,打印指針值藏漢(忽略警告):

printf("%s [%p]\n", ++*p, p); 
printf("%s [%p]\n ", *p++, p); 
printf("%s [%p]\n ", ++*p, p); 

nowledge [0x7fff6f5519e0] 
nowledge [0x7fff6f5519e8] 
s [0x7fff6f5519e8] 
+3

很好的答案,但不是那些打印UB,因爲你不能保證函數參數被評估的順序是什麼? – JoeFish

+0

謝謝fljx。這是一個非常好的解釋。 – sourabh912

+0

@JoeFish - 是的,你是對的。這些表達式有副作用,這就是爲什麼我說忽略編譯器警告。在生產代碼中,我們不能依賴這樣的表達式。感謝問! – j4x

5

第一個遞增* p並顯示字符串(將其設置爲知識庫中的n)。第二個顯示字符串* p然後遞增p(將它移動到「is」)。第三個增量* p然後顯示字符串(從「is」中的s開始)。

2

增量後綴運算符(p++)評估的值爲p。增量前綴運算符(++p)評估的值爲p+1

在您的第二個printf中,*p++評估爲*p將評估的值,但具有增加p的副作用。

1

當面對運營商的棘手序列,它往往容易把它改寫作爲一系列簡單的陳述。您的塊變爲:

p[0]++; //skips over the 'k' in knowledge 
printf("%s", *p); 
printf("%s", *p); 
p++;  //moves to the next word 
p[0]++; //skips over the 'i' in is 
printf("%s", *p);