[英]Difference between char* and char[]
我知道這是一個非常基本的問題。 我很困惑為什么以及以下內容有何不同。
char str[] = "Test";
char *str = "Test";
char str[] = "Test";
是一個chars
數組,用“Test”中的內容初始化,而
char *str = "Test";
是指向文字(常量)字符串“Test”的指針。
它們之間的主要區別在於第一個是數組,另一個是指針。 數組擁有它的內容,它恰好是"Test"
的副本,而指針只是指向字符串的內容(在這種情況下是不可變的)。
不同之處在於使用的堆棧內存。
例如,當為微控制器編程時,為堆棧分配的內存很少,這會產生很大的不同。
char a[] = "string"; // the compiler puts {'s','t','r','i','n','g', 0} onto STACK
char *a = "string"; // the compiler puts just the pointer onto STACK
// and {'s','t','r','i','n','g',0} in static memory area.
一個指針可以重新指向別的東西:
char foo[] = "foo";
char bar[] = "bar";
char *str = foo; // str points to 'f'
str = bar; // Now str points to 'b'
++str; // Now str points to 'a'
增加指針的最后一個示例表明您可以輕松地迭代字符串的內容,一次一個元素。
一種是指針,一種是數組。 它們是不同類型的數據。
int main ()
{
char str1[] = "Test";
char *str2 = "Test";
cout << "sizeof array " << sizeof(str1) << endl;
cout << "sizeof pointer " << sizeof(str2) << endl;
}
輸出
sizeof array 5
sizeof pointer 4
首先
char str[] = "Test";
是一個包含五個字符的數組,使用值"Test"
加上空終止符'\\0'
初始化。
第二
char *str = "Test";
是指向文字字符串"Test"
的內存位置的指針。
從 C++11 開始,第二個表達式現在無效,必須寫成:
const char *str = "Test";
該標准的相關章節是附錄C第1.1節:
更改:字符串文字常量
字符串文字的類型從“字符數組”更改為“常量字符數組”。 char16_t 字符串文字的類型從“某種整數類型的數組”更改為“const char16_t 的數組”。 char32_t 字符串文字的類型從“某種整數類型的數組”更改為“const char32_t 的數組”。 寬字符串文字的類型從“wchar_t 數組”更改為“const wchar_t 數組”。
基本原理:這避免了調用不合適的重載函數,該函數可能期望能夠修改其參數。
對原始特征的影響:更改為明確定義的特征的語義。
"Test"
是一個包含五個字符(4 個字母,加上空終止符)的數組。
char str1[] = "Test";
創建 5 個字符的數組,並將其命名為str1
。 您可以隨意修改該數組的內容,例如str1[0] = 'B';
char *str2 = "Test";
創建 5 個字符的數組,不命名它,並創建一個名為str2
的指針。 它將str2
設置為指向該 5 個字符的數組。 您可以按照指針隨意修改數組,例如str2[0] = 'B';
或*str2 = 'B';
. 您甚至可以重新分配該指針指向其他地方,例如str2 = "other";
.
數組是引號中的文本。 指針只是指向它。 你可以用它們做很多類似的事情,但它們是不同的:
char str_arr[] = "Test";
char *strp = "Test";
// modify
str_arr[0] = 'B'; // ok, str_arr is now "Best"
strp[0] = 'W'; // ok, strp now points at "West"
*strp = 'L'; // ok, strp now points at "Lest"
// point to another string
char another[] = "another string";
str_arr = another; // compilation error. you cannot reassign an array
strp = another; // ok, strp now points at "another string"
// size
std::cout << sizeof(str_arr) << '\n'; // prints 5, because str_arr is five bytes
std::cout << sizeof(strp) << '\n'; // prints 4, because strp is a pointer
對於最后一部分,請注意 sizeof(strp) 將因架構而異。 在 32 位機器上,它將是 4 個字節,在 64 位機器上它將是 8 個字節。
我們來看看以下幾種聲明字符串的方式:
char name0 = 'abcd'; // cannot be anything longer than 4 letters (larger causes error)
cout << sizeof(name0) << endl; // using 1 byte to store
char name1[]="abcdefghijklmnopqrstuvwxyz"; // can represent very long strings
cout << sizeof(name1) << endl; // use large stack memory
char* name2 = "abcdefghijklmnopqrstuvwxyz"; // can represent very long strings
cout << sizeof(name2) << endl; // but use only 8 bytes
我們可以看到使用 char* variable_name 聲明字符串似乎是最好的方法! 它以最少的堆棧內存來完成這項工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.