2012-02-20 93 views
5

有人可以解釋下面的代碼的輸出指向指針運算

char* a[] = {"ABC123", "DEF456", "GHI789"}; 
char **p = a; 
cout<<++*p<<std::endl; 
cout<<*p++<<std::endl; 
cout<<++*p<<std::endl; 

輸出:

BC123 
BC123 
EF456 

有什麼困惑,我是++ * p的不同的行爲和* P ++。我期待的輸出是:

ABC123 
DEF456 
GHI789 
+6

運算符優先級。添加一些括號,它會明白... – jrok 2012-02-20 10:21:32

回答

3
char* a[] = {"ABC123", "DEF456", "GHI789"}; 
char **p = a; 
cout<<++*p<<std::endl; // 1 
cout<<*p++<<std::endl; // 2 
cout<<++*p<<std::endl; // 3 

在第一行第一*p將指向所述元件的陣列"ABC123"中和++移動一個前進等等「BC123」被打印。

在線2 *p仍然指向BC123所以這是打印,然後一旦打印++進行。這將指針移至數組中的第二個元素

在第3行上它與第1行相同。您已獲取p(現在是數組中的第2個元素)的內容並移動了該字符串中的一個字符,因此,印刷EF456

(也可以看看在這裏Pointer arithmetic on string type arrays, how does C++ handle this?,因爲我認爲,要了解眼前發生的事情的理解,它可能是有用的)

要打印你所期望的下面將工作:

cout<<*p++<<std::endl; 
cout<<*p++<<std::endl; 
cout<<*p++<<std::endl; 

或者

cout<<*p<<std::endl; 
cout<<*(++p)<<std::endl; 
cout<<*(++p)<<std::endl; 

或各種其他方式(考慮到優先正如其他人所說)

0

++*p在打印前執行。所以增加指針,然後打印。打印後執行 *p++。打印,然後增加。

0

只是一個猜測,但我認爲,因爲你正在使用cout<<++*p<<std::endl;遞增推理指針,你實際上做的是遞增字符串開始處的字符數,然後把它輸出到標準輸出。

同樣cout<<*p++<<std::endl;正在輸出後遞增字符,因此最終的cout<<++*p<<std::endl;結果爲兩個增量。

而應該試試這個,看看它是否工作

cout<<*(++p)<<std::endl; 
cout<<*(p++)<<std::endl; 
cout<<*(++p)<<std::endl; 
+1

該輸出的最後一行導致它不幸地出現繁榮。 '++ p'將它移動到數組的末尾 – Firedragon 2012-02-20 11:00:12

4

也許這會有所幫助。您的例子就是大致相當於此:

++(*p); 
cout << *p << '\n'; 

cout << *p << '\n'; 
++p; 

++(*p); 
cout << *p << '\n'; 

沒有括號,*p++被解析爲*(p++)因爲後綴增量已經得到了比引用操作更高的優先級。儘管如此,增量仍然是在整個表達式之後完成的。

另一方面,前綴增量和*具有相同的優先級,所以++*p被從右向左解析爲++(*p)。知道前綴增量必須在表達式之前完成,現在可以將整個圖片放在一起。

+0

我明白了......我只是將運算符優先級放到圖片中,完全忘記了關聯性..謝謝 – 2012-02-20 10:50:54

1

根據C++運算符優先級表,後置增量優先級高於解引用(*)運算符,前置增量和解引用運算符優先級相同。另外預增和取消引用操作符是從右到左的關聯。

所以在第一行(cout<<++*p<<std::endl;)中,*和++從右到左評估(先取消引用,然後增加)。現在p仍然指向第一個數組(因爲它沒有改變),但(* p)指向第一個字符串的第二個字母(輸出顯示了這個事實)。

在第二行(cout<<*p++<<std::endl;)中,首先評估後增量(在檢索舊值p後),並且p遞增,現在指向第二個數組。但是在增量之前,p的值用在表達式中,第二行的輸出與第一行完全一樣。

在第三行中,首先解除引用p(指向第二個數組的第一個字母),然後遞增(指向第二個數組的第二個字母),並打印該值。