2013-07-25 111 views
2

下面是我想知道旁邊註釋中2個問題的答案的代碼。請幫我C++中的字符串和指針

#include<iostream> 

using namespace std; 

int main() 
{ 
    char *p="Hello"; 
    cout <<*p;  //gives H 
    cout <<*(p++); //also gives H.Why? 
    cout <<*(p++); //gives e. 
    cout <<*(p++); //gives l. 
    cout <<*(p++); //gives l. 
    cout <<*(p++); //gives o. 
    cout <<*(p++); //gives no output.Why? It should give some garbage value! 
} 
+0

使'const char *',而不是'char *'。 – chris

+0

@chris:這是一個不同的問題。我想了解當前代碼的奇怪輸出。 –

+0

p ++表示後增量,取第一個值,然後遞增 –

回答

3

p ++所做的是遞增p並返回p的舊值,因此*(p ++)將始終返回存儲在* p處的字符,並且在語句* p將指向下一個字符之後。

cout <<*(p++); //gives 0. 

這實際上並沒有給0,它使字符「o」,在Hello的最後一個字符。

cout <<*(p++); //gives no output.Why? It should give some garbage value! 

這將輸出終止字符串的NUL字符。這是一個不可打印的字符,並且您看到此輸出的位置,您可能看不到任何可能的原因,因爲該軟件決定不打印非printable。如果你看一下輸出例如十六進制轉儲,你可以看到NUL右後○:

00000000 48 48 65 6c 6c 6f 00        |HHello.| 

如果添加另一個cout <<*(p++)威力看到垃圾輸出,或者該程序可能會崩潰,或者可能會發生其他事情,因爲這會是「未定義的行爲」。

+0

:感謝您的支持Sir.How我可以看到十六進制轉儲?我正在使用linux與g ++。 –

+0

像下面這樣將程序的輸出輸出到'hd'或'hexdump -C':'programname | hexdump -C' – Joni

+0

這些'00000000'在開始處表示什麼? –

4

*(p++)'h',因爲你首先要問的價值比增加你的指針的位置,並在最後一行同樣的事情。

+0

但是不會執行第一個p ++',因爲它在括號內 –

+0

Postfix op返回原始值。前綴返回增加 – Borgleader

+0

否在該點的值被賦予操作後完成增量 – Engine

3

p++實際上請求值,然後增加它。如果你想增加它,然後增加值,使用++p

對於你的最後一個問題,C字符串的最後一個值始終爲'\0'。在大多數情況下,在終端上不會打印任何內容,但這是C++標準未定義的行爲。

+1

「'\ 0」。終端上沒有任何內容。「 - 我們被告知Insane編碼器就是這種情況,但行爲不是由C++標準定義的,它不打印任何東西不應該被依賴。 –

+0

@TonyD感謝精度,我編輯了答案 –

4
  1. 如果你在代碼中使用p++任何地方,說:

    <some code> p++ <some code> 
    

    這相當於

    <some code> p <some code>; 
    p = p + 1; 
    

    相反,如果你寫:

    <some code> ++p <some code> 
    

    這是相當於

    p = p + 1; 
    <some code> p <some code> 
    

    這應該回答你的第一個問題。

  2. C風格的字符串自動以\ 0字符結尾。所以,如果你聲明:

    char *p="Hello"; 
    

    ,編譯器會自動添加一個\ 0到該字符串爲您的結束(否則如printf函數不會知道,當字符串結束)。所以,你的字符串實際上是:

    "Hello\0" 
    

    如果你嘗試,雖然推指針進一步,你會在無效的內存結束了,你可能會遇到的任何東西(垃圾,這可能是一系列的零和)

+1

這裏沒有未定義的行爲。 「Hello」的第六個字符是「\ 0」,每次都有保證。 –

+0

我低估了,因爲你錯了。 「你好」的第六個字符是''\ 0''。沒有什麼不明確的。 –

+0

@LeeDanielCrocker我被OP的'cout << *(p ++)誤導了; //給0'(而不是'//給o')。事實上,他仍然在有效的記憶中。我的錯。編輯答案。 – Spook

1

第一個*(p++)給出「H」,因爲++運算符被定義爲首先給出其當前值,然後執行增量。最後的*(p++)返回字符'\0',因爲字符串文字"Hello"指向一個包含SIX字符的數組,最後一個字符是'\0'

0

這樣做:

{ 
    char *p="Hello"; 
    cout <<*p;  //gives H. 
    cout <<*(++p); //gives e. 
    cout <<*(++p); //gives l. 
    cout <<*(++p); //gives l. 
    cout <<*(++p); //gives o. 
    cout <<*(++p); //gives 0. 
    cout <<*(++p); //will either be a garbage value or throw an exception 
} 

該++則p遞增指針,然後返回值。 p ++將值推入堆棧,增加指針並彈出堆棧以返回它。它也可能使用寄存器;實現細節是編譯器的一種。

1

這是因爲當使用後增量(例如您的p++)時,在之前,增量完成後評估值爲

因此,在你的代碼,你的第一個cout << *(p++);將打印「H」,因爲它會之前評估的p價值的分配,這是p的地址,然後的p值遞增。

要在評估之前遞增p的值,請使用增量前++p

因此,這是在你的代碼會發生什麼:

int main() 
{ 
    char *p="Hello"; 
    cout <<*p;  //gives H 
    cout <<*(++p); //this time it will give e 
    cout <<*(++p); //gives l. 
    cout <<*(++p); //gives l. 
    cout <<*(++p); //gives o. 
    cout <<*(++p); //gives no output since the character after a string is always \0 (credit to answer below) 
} 

希望這有助於! = D

+1

它不應該給垃圾。它給出了''\ 0',因爲所有的字符串都以'\ 0'結尾。 – Rapptz

0
char *p="Hello"; 
cout <<*p;  //gives H 
cout <<*(p++); //also gives H.Why? 

因爲後評估會在評估後增加p。 要增加p前評估,使用*(++p)

cout <<*(p++); //gives e. 
cout <<*(p++); //gives l. 
cout <<*(p++); //gives l. 
cout <<*(p++); //gives 0. 
cout <<*(p++); //gives no output.Why? It should give some garbage value! 

有一個填充\0在每一個C風格的字符串。