2012-04-12 31 views
1
char i; 
for(i=0;i<16;i++) 
    printf("%c","asdf"[i]); 
i=1; 
if("123"[i]==1) 
    i=1; 
if("456"[4]==1) 
    i=1; 
if("789"[1]==1) 
    i=1; 

輸出爲訪問字符:來自未在一個變量(C)聲明爲「串」

asdf 123 456 

看似大部分「串」的是後在存儲器中彼此直接。我不認爲這是隨機的,還是它? 此外,當我在char-access-expression中使用int變量而不是i時,程序失敗,這不是第一個(這裏是asdf [i])。例如如果(「123」[j] == 1)

有人可以向我解釋嗎?

+0

編譯器通常會將所有常量字符串收集到「字符串表」中。這樣做可能會去除重複的字符串;例如:「hello \ 0」和「lo \ 0」最終可能會在字符串表中摺疊。 – ninjalj 2012-04-12 19:54:37

+0

但是爲什麼「789」不在這張桌子上呢?這取決於訪問索引,或者它看起來如此? – user1329846 2012-04-14 05:44:31

+0

@ user1329846:可能是編譯器在編譯時計算了「」789「[1]」,但對於「456」[4]'沒有這樣做。內存中字符串的位置不是由C標準定義的,所以在這裏沒有任何保證,這就是爲什麼你應該避免你想要做的事情。 – 2012-04-14 12:55:39

回答

7

常量字符串通常與程序代碼分開存儲,並且它們在內存中緊密排列在一起並不奇怪。但是你不應該依賴這個。

您的程序有未定義的行爲如果您嘗試使用不同的編譯器運行代碼,可能會發生不同的事情。例如,當我使用gcc 4.3.4在ideone上運行您的代碼時,它不會輸出與您所得到的相同的結果。

+0

對不起,是高興地,但實際上我仍然想明白爲什麼我的示例中的所有字符串都不是直接在另一個字符串之後,而是依賴於訪問索引(例如i)。特別是:爲什麼程序因爲這個索引使用int而失敗? – user1329846 2012-04-14 11:31:16

+0

@ user1329846:關於未定義行爲的一個很酷的事情是*任何*都可能發生,包括混淆的行爲,似乎沒有任何明顯的邏輯解釋。 *而不是試圖*理解未定義的行爲,你應該嘗試*避免*它。但是,如果您真的想要了解它,請拆開生成的機器代碼,並查看幕後發生的事情。 – 2012-04-14 12:03:51

+0

我也這麼認爲,直到我得到ninjalj的評論。當有收集字符串的原因(去除它們)時,必須有一個理由不對每個字符串進行這種操作。我有點不喜歡,所以我想嘗試避免反彙編... – user1329846 2012-04-14 12:34:40