簡體   English   中英

char* 和 char[] 之間的區別

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM