2015-09-10 39 views
0

這是我的教科書中的練習。我需要找到這個代碼的輸出。瞭解此代碼的輸出

#include<iostream> 
using namespace std; 
int main() 
{ 
    int x[]={10,20,30,40,50}; 
    int *p,**q,*t; 
    p=x; 
    t=x+1; 
    q=&t; 
    cout<<*p<<","<<**q<<","<<*t++; 
    return 0; 
} 

輸出是

10,30,20 

在這裏,我不明白**問的聲明,以及如何它的價值出來是30.我還注意到,改變了過去的聲明

cout<<*p<<","<<**q<<","<<*t; 

改變輸出到

10,20,20 

有人能解釋幕後發生了什麼嗎?提前致謝。

+6

儘快拋出教科書。 – interjay

+1

閱讀序列點(https://en.wikipedia.org/wiki/Sequence_point)和http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points – Abhineet

+1

@Abhineet我認爲這個話題是對於初學者來說太過先進了,這本蹩腳的書的作者需要閱讀它。 +1到interjay - 扔掉這個。 – Slava

回答

0

pt都是類型pointer to int的,q是類型pointer to (pointer to int)

* operator使一個指針指向一個參考的。

因此*pint&類型,*t也是如此。 *q是類型int*&的(讀reference to a pointer to int

你想在這裏打印int值,因此必須使用* operator第二次。

所以**q只是作出pointer to a pointer to intreference to int


我忘了提到它:這個過程被稱爲dereferencing pointers

也許在這一側的descirption會給你一個更好的洞察力: http://www.cplusplus.com/doc/tutorial/pointers/

-2

++運算符具有較高的比precedence < < 當程序執行該事件是:

int x[]={10,20,30,40,50}; 
int *p,**q,*t; 
p=x; 
t=x+1; 
q=&t; 
cout<<*p<<","<<**q<<","<<*t++; //1st change value of t to t+1, 
//but return old t in place^
//then to output stream 'p'=10, then 'q'=new 't'=old 't'+1=30, 
//then old 't'=20 which is returned by sufix ++ operator 
+0

不能保證't ++'會在以前發生讀取'** q'的值。所以行爲是不確定的。 – interjay

+0

對於未定義的行爲描述事件順序沒有意義。這是這次發生的事。 – Slava

2

這裏, q是指向int的指針,它被設置爲指向t。所以*qt相同,並且**q*t。這意味着cout表達式可以改寫爲:

cout<<*p<<","<<*t<<","<<*t++; 

在這裏你可以看到t被讀取和表達的不同部分修改,標準說,沒有規定在這些地區執行順序。因此t可能會在讀取之前或之後(或甚至在讀取它時)進行修改。當這種事情發生時,我們得到未定義的行爲:任何事情都可能發生。特定的編譯器可能會在特定的計算機上給出特定的結果,但不能保證您總能得到此結果。

所以這個練習是無效的,並且試圖找出爲什麼看到特定的輸出沒有意義。

在另一方面,第二行,你嘗試:

cout<<*p<<","<<**q<<","<<*t; 

是完全有效的,因爲它不修改t任何地方。

+0

行爲真的沒有定義,或者只是結果不明確? – user2079303

+1

@ user2079303這是未定義的。從標準:「如果一個標量對象上的一側效應不是相對於同一個標量對象上的另一側效應或者是使用相同標量對象的值計算的值,而且它們不可能是併發的(1.10),則行爲未定義「。 – interjay