2011-10-25 52 views
2

這兩個初始化有什麼區別?C「string」init - 哪個更好?

char a[] = "string literal"; 

char *p = "string literal"; 
+0

重複:stackoverflow.com/questions/7886972/difference-between-char-and-char – tinman

+0

如果這被問了這麼多次,爲什麼人們回答而不是關閉? – sidyll

+1

@sidyll:因爲人們回答問題以獲得代表而不是檢查副本 – tinman

回答

3

每個強制編譯器在靜態內存中創建(至少在概念上)只讀的字符串文字。

第一個然後使用它來初始化數組的內容。字符串文字只是用來選擇它的大小,並初始化它。

第二個創建一個直接指向原始字符串文字本身的指針。

他們之間沒有真正的更好或更壞。他們只是不同而已。例如,數組通常使用更多的內存(有一個字符串文字,然後在你的數組中有一個完整的字符串文本副本)。因爲它是一個普通的數組,所以你可以根據需要修改它。

直接指向字符串文字的指針通常會保存一些內存。這也意味着你可以爲指針指定一個不同的值,以便它(例如)在不同時間指向不同的字符串文字。你是而不是,但是,允許修改它指向的數據 - 這樣做會導致未定義的行爲。

17

儘管兩者看起來很相似,並且經常交替使用,但它們確實意味着不同的事情。第一行:

char a[] = "string literal"; 

...創建一個足夠大的數組來保存字符串,包括它的NUL終止符。它用你指定的字符串文字初始化這個數組。此版本的一個好處是可以在稍後修改數組。此外,即使在編譯時,陣列的大小也是已知的,所以您可以使用sizeof運算符來確定它的大小。例如:

printf("%u\n",unsigned(sizeof(a))); // Will display 15, which is the array's size 
            // including the NUL terminator 

第二行:

char *p = "string literal"; 

...只是設置一個指針指向一個字符串。這比第一個版本更快,但是您有缺點,即不應更改文字,因爲它可能位於標記爲只讀的頁面中。您還有一個缺點,要知道字符串的長度,您將需要使用strlen()函數,因爲sizeof運算符只會給你指針變量的大小。例如:

printf("%u\n",unsigned(sizeof(p))); // Will likely display 4 or 8, depending on 
            // whether this is a 32-bit or 64-bit build 
printf("%u\n",unsigned(strlen(p))); // Will display the correct length of 14, not 
            // including the NUL terminator 

至於哪個更好,這取決於您將如何處理這些變量。如果不需要對字符串進行任何更改,請使用更高版本,但執行char *更改爲const char *,以便您不會意外嘗試更改指向的字符。如果您打算更改數據,請使用以前的基於陣列的版本,該版本允許您在初始化後更改數組。

+2

在第二個例子中使用'char const *'實際上比較聰明,但編譯器有義務接受'char *'版本,因爲標準中向後兼容的疣。 –

+0

@larsmans,我已將此事實添加到我的答案中,以使其更加完整。謝謝... –

+1

我看到你已經添加了一些C++輸出示例的答案,但OP沒有標籤它C ... –

0

取決於你需要什麼。

char a[] = "string literal"; 

創建可變字符陣列具有自動存儲持續時間。這是合法的:

a[0] = 'c'; 

在另一方面...

char *p = "string literal"; 

創建一個指向只讀存儲器。聲明應該是

const char *p = "string literal"; 

你不能合法地修改p指向什麼。

0

第一個聲明一個數組並填充它(通過逐個設置元素,直到包含結束空字節)。該數組可以修改。

第二個聲明一個指針,並通過將其設置爲一個常量字面值來填充它。您可以修改指針(例如使其指向其他地方),但不能修改指向它的常量字符串(大多數系統將放在只讀段中)。

0

一個給你一個填充你指定數據的數組,第二個給你一個指向某個內存(通常只讀)的指針,包含你指定的數據。

爲了讓「你會得到什麼」更加清晰的區別,試試這個:

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    char a[] = "string literal"; 
    char *b = "string literal"; 

    printf("a is %lu bytes, b is %lu\n", (unsigned long) sizeof a, 
             (unsigned long) sizeof b); 

    return EXIT_SUCCESS; 
} 

這裏是一個live demo與上面的代碼。