2012-02-07 80 views
2
for(int i=0;i<10;i++) 
{ 
    cout << i+"passs" << "\n"; 
} 

此輸出這樣產生的輸出如下:爲什麼這個int和字符串連接給在C++

passs 
asss 
sss 
ss 
s 

現在,我的想法是,我們看到的指針操作,其中計數器i被添加到passs字符指針,我們看到從「通過」指針+ 0,「通過」指針+ 1等輸出。

問題爲什麼它不停止,當它達到空字符,因爲它打印5空白行。

接下來是cout << "passs"+i << "\n";打印相同的東西。我認爲這應該已經從第二個位置打印出所有空行,因爲此時傳遞指針應該可能來自最後一個位置。在閱讀我在這裏寫的內容時,可能有意義的是看到第二個cout的輸出結果是這樣。

我想知道我是否正確思考,如果還有更多這一點,我不理解?

+0

正如你已經意識到的那樣,它不是一個「連接」。所以問題標題讓你看起來比你真正的困惑;-) – 2012-02-07 13:43:15

+0

@Steve大聲笑,應該有適當的措辭 – gizgok 2012-02-07 13:47:02

回答

2

您的初始推理是正確的。你在這裏做指針運算,所以輸出的前六行(第六行是\0\n)是好的。但是當你離開字符串的末尾時,你會遇到麻煩。循環中沒有任何東西可以停止迭代,所以你的程序理論上可以用"passs" + 6,7,8和9做任何事情。讓我們來看看爲什麼。

回想一下,字符串文字的類型爲const char *。在內存部分現貨由編譯器決定,你必須:

| p | a | s | s | s | \0 | * | * | * | * | 

*符號代表不確定內存的沒有人的土地過去的字符串的結尾。隨着您的for-loop運行,它開始於p並向前走。由於我們正在處理一個const char *,每一步都將是一個字節。在每個步驟中,cout都會嘗試儘可能多地進行打印,直到達到空字符爲止(如您在輸出中看到的那樣)。但是你不能嘗試從無人區域打印任何東西。這樣做會導致未定義的行爲。就你而言,該內存包含不可打印的字符。

所以總之,你大部分是正確的。 cout確實在到達空值時停止打印。但是for循環沒有。

+0

「你不能嘗試從無人地帶打印任何東西,這樣做會導致不確定的行爲。 「 - 僅僅是*創建指針*導致未定義的行爲。這樣做的動機是(1)''passs''的內存可能恰好位於地址空間的最後,因此將6加到地址空間會導致溢出,(2)C++旨在允許指針溢出導致硬件故障(儘管不是無符號整型溢出,必須環繞)的古老和特殊體系結構。所以,無論您是否打印,「6 +」都會傳遞「UB」。 – 2012-02-08 10:30:05

+0

我以爲你保證能夠解決(但不是取消引用)一個過去的一端,以支持標準庫算法。所以在這種情況下有+6的指針是可以的,但+7到+9不是。無論如何,這是一個很好的觀點,謝謝你的提出。 – 2012-02-08 13:49:13

+0

對不起,你說得對,我應該在評論中的兩個地方說7而不是6。這意味着,正如你所說,提問者循環中的「第一個」UB取消了「6 +」passs「'。 「下一個」UB正在計算「7 +」通行證「'。 – 2012-02-08 14:55:59

2

這是因爲一個字符串文字作爲指針(指針運算)處理:增加一個指向整數向前移動指針:

"passs" + 1 = "asss" 
"passs" + 2 = "sss" 
"passs" + 3 = "ss" 

添加一個數字作爲一個字符串,你應該使用:

cout << i << "passs" << "\n"; 
2

你是對的,pointer + integerinteger + pointer都是操作指針運算並給出一個新指針,因此輸出是「正常」。

4

你說得對。

字符串文字被解釋爲指向字符串開頭的指針。給這個添加一個int是一個指針增量。

一旦你走到最後,你會陷入未定義的行爲 - 在你的系統上看起來相當無害,但可能在另一個coredump結束。

相關問題