2011-07-14 53 views
2

我正在嘗試在C中學習字符串時,遇到此代碼。奇怪的C字符串輸出

#include <stdio.h> 
int main(){ 
     char s[] = "Hello world"; 
     printf("%s" , s); 
     printf("%s" , &s); 
     return 0; 
} 

兩者都以Hello World作爲輸出。根據我的理解,這個輸出對於第一種情況是正確的。它是如何工作的第二個?請澄清。

+3

試着接受你以前的回答 – Aravindhan

+1

該怎麼做......我是新來的SO ?? – Pritpal

+0

@Pritpal:您在每個問題上點擊您想接受的答案旁邊的勾號。 – Puppy

回答

1

只是它所可能是值得的,如果你想獲得的技術,你的第二個版本:

printf("%s" , &s); 

是未定義行爲,只有偶然的作品。通過明確地獲取地址,你得到了數組的地址(這很好),但是結果的類型是「指向12個字符數組的指針」,而不是「指向char的指針」類型,如printf' s%s的轉換。由於類型不匹配,結果是未定義的行爲。

然而,事實上,這是純粹是的技術性 - 代碼將在我意識到的每個C實現上都很好地工作。

如果你想證明存在的差異,你可以很容易地做到這一點。例如:

char string[] = "hello world"; 

printf("without &: %p, %p\n", (void *)string, (void *)(string+1)); 
printf("with &: %p, %p\n", (void *)&string, (void *)(&string+1)); 

在第一種情況下,string衰減到字符指針,所以在第一行,第二指針將是恰好一個大於第一。在第二行中,我們將一個指針添加到一個字符數組的指針,所以當我們添加一個時,它實際上會添加數組的大小。我的機器上運行此,我得到的結果是這樣的:

without &: 0038F96C, 0038F96D 
with &: 0038F96C, 0038F978 
2

s&s返回相同的地址,因此。該地址是來自「Hello world」的「H」存儲位置。

因爲,
陣列的名稱衰變到所述第一元件的地址在一個陣列&
第一個元件的地址是相同陣列的地址。

6

取一個數組的地址與獲取它的第一個元素的地址相同。當使用數組的名稱時,它也衰減到它的第一個元素的地址 - 所以表達式s&s產生相同的結果。

+0

對於整數數組也是如此? – Pritpal

+0

@Pritpal:也適用於整數數組,它與數據類型無關。 –

4

s返回數組中第一項的地址,&s返回數組本身的地址 - 這些碰巧是一樣的。

一般而言,如果您希望更加明確,則還可以使用表達式&s[0]返回第一個項目的地址。

-1

s等於& s [0],所以我們傳遞s [0]的地址而不是指向s [0]的指針的地址,因此它將在第二種情況下打印Hellow世界。

s是數組的名稱而不是指針。

0

個char []與字符* S是一個性格特徵指針指向數組的第一個元素(它包含的地址第一個元素存儲)。 我們也可以通過存儲第一個字符的地址來存儲字符串。在執行期間,計算機開始逐個從該地址獲取字符,並創建一個字符串,直到達到空字符('\ 0')。 在上面的例子's'和'%s'表示相同的值(起始字符的地址)希望你能得到它。 如果你使用char s [10](固定長度數組),你會理解所有的東西。