回答
每個強制編譯器在靜態內存中創建(至少在概念上)只讀的字符串文字。
第一個然後使用它來初始化數組的內容。字符串文字只是用來選擇它的大小,並初始化它。
第二個創建一個直接指向原始字符串文字本身的指針。
他們之間沒有真正的更好或更壞。他們只是不同而已。例如,數組通常使用更多的內存(有一個字符串文字,然後在你的數組中有一個完整的字符串文本副本)。因爲它是一個普通的數組,所以你可以根據需要修改它。
直接指向字符串文字的指針通常會保存一些內存。這也意味着你可以爲指針指定一個不同的值,以便它(例如)在不同時間指向不同的字符串文字。你是而不是,但是,允許修改它指向的數據 - 這樣做會導致未定義的行爲。
儘管兩者看起來很相似,並且經常交替使用,但它們確實意味着不同的事情。第一行:
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 *
,以便您不會意外嘗試更改指向的字符。如果您打算更改數據,請使用以前的基於陣列的版本,該版本允許您在初始化後更改數組。
在第二個例子中使用'char const *'實際上比較聰明,但編譯器有義務接受'char *'版本,因爲標準中向後兼容的疣。 –
@larsmans,我已將此事實添加到我的答案中,以使其更加完整。謝謝... –
我看到你已經添加了一些C++輸出示例的答案,但OP沒有標籤它C ... –
取決於你需要什麼。
char a[] = "string literal";
創建可變字符陣列具有自動存儲持續時間。這是合法的:
a[0] = 'c';
在另一方面...
char *p = "string literal";
創建一個指向只讀存儲器。聲明應該是
const char *p = "string literal";
你不能合法地修改p
指向什麼。
第一個聲明一個數組並填充它(通過逐個設置元素,直到包含結束空字節)。該數組可以修改。
第二個聲明一個指針,並通過將其設置爲一個常量字面值來填充它。您可以修改指針(例如使其指向其他地方),但不能修改指向它的常量字符串(大多數系統將放在只讀段中)。
一個給你一個填充你指定數據的數組,第二個給你一個指向某個內存(通常只讀)的指針,包含你指定的數據。
爲了讓「你會得到什麼」更加清晰的區別,試試這個:
#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與上面的代碼。
- 1. 哪個更好,「var array = ...」或「string [] array = ...」?
- 2. 哪個更好?
- 3. 哪個更好
- 4. 哪個更好?
- 5. 哪個listview更好?
- 6. C內在效率 - 哪個更好?
- 7. Xamarin,Objective C或Phonegap哪一個更好?
- 8. 哪個單例實現更好C#
- 9. C++/CLI與COM - 哪個更好?
- 10. C setjmp.h和ucontext.h,哪個更好?
- 11. 哪一個更好?
- 12. 哪一個更好?
- 13. 哪個JSON更好
- 14. 哪一個更好?
- 15. 從記憶的角度來看哪一個更好String [] /列表<String>
- 16. 在Java中使用String或StringBuffer:哪個更好?
- 17. Vector.contains()或Hashtable.get()哪個更好
- 18. XPath性能 - 哪個更好?
- 19. 日食哪個-vm更好?
- 20. DataTable或IList?哪個更好?
- 21. 哪個撐型更好?
- 22. 空元素 - 哪個更好
- 23. 哪個更好c89或c99
- 24. typeof undefined。哪個更快更好?
- 25. min或gzip,哪個更好?
- 26. 哪個更好? OpenCyc或ConceptNet?
- 27. 哪個更好,Nagios或Sensu?
- 28. jqGrid或dataTable,哪個更好?
- 29. 哪個git模型更好?
- 30. ActiveX vs Delphi,哪個更好?
重複:stackoverflow.com/questions/7886972/difference-between-char-and-char – tinman
如果這被問了這麼多次,爲什麼人們回答而不是關閉? – sidyll
@sidyll:因爲人們回答問題以獲得代表而不是檢查副本 – tinman