[英]Why can´t we assign a new string to an char array, but to a pointer?
我試圖將一個字符串重新分配給一個預先初始化的數組 a[],但我得到的只是一個錯誤
main()
{
char a[] = "Sunstroke";
char *b = "Coldwave";
a = "Coldwave";
b = "Sunstroke";
printf("\n %s %s",a,b);
}
[錯誤]:從類型 'char *' 分配到類型 'char[10]' 時類型不兼容。
char a[] = "Sunstroke";
但它沒有用...
但是在指針的情況下,就像上面的程序一樣..
要了解這里發生了什么,有兩個語言規則很重要:
了解像"Sunstroke"
這樣的字符串文字是什么也很重要。 它是一個常量字符的靜態數組,大到足以容納以終止符結尾的字符串的所有字符。 所以在這種情況下,它是一個const char[10]
數組,包含九個字符,后跟零值終止符。 作為static ,數組在程序的生命周期內存儲在內存中的某處。
char a[] = "Sunstroke";
這將創建一個本地數組,並通過從字符串文字中復制字符來初始化它。
char *b = "Coldwave";
這將創建一個指針,並將其初始化為指向文字本身。 請注意,這是危險的:文字是const
,但指針不是,因此您可以編寫嘗試修改文字的代碼,從而給出未定義的行為。 這種轉換已被棄用(當然在 C++ 中,我不確定 C),因此編譯器應該給你一個警告。 您已經啟用了所有可能的編譯器警告,不是嗎?
a = "Coldwave";
這會嘗試重新分配數組,但由於數組不可分配而失敗。 沒有特別好的理由為什么他們不是。 這就是語言進化的方式。
b = "Sunstroke";
這會重新分配指針以指向不同的文字。 這很好(除了上面提到的缺少const
之外)。
如果您需要操作字符串,則:
<string.h>
的庫函數(或您自己編寫的代碼)來操作這些數組中的字符;std::string
類為您處理內存管理、分配等。諸如“Coldwave”之類的硬編碼字符串文字實際上是char[]
(字符數組)類型——但修改它們是未定義的行為( C99 :6.4.5.6)。 但是請注意,下面的b
仍然是一個char*
(字符指針):
char *b = "Coldwave";
已為其分配了char[]
。 沒關系。 但它與此不同:
char a[] = "Coldwave";
這是char[]
的初始化。 您只能在聲明變量時初始化一次,並且初始化是您可以通過這樣的賦值填充數組或其他復合類型(例如結構)的唯一情況。 但是,您不能這樣做:
char c[] = a;
因為當在賦值的右側使用時,數組變量充當指向它們所代表的數組的指針,這就是char *b = a
起作用的原因。
所以你不能用上面的變量做到這一點的原因:
a = b;
// or
a = "Sunstroke";
是因為那會將char*
分配給char[]
—— 不好; 你只能反過來做。
在C的情況下,如果我們查看c99 草案標准第6.5.16
節賦值運算符第2段說:
賦值運算符應有一個可修改的左值作為其左操作數。
和第6.3.2.1
節左值、數組和函數指示符第1段說:
[...]可修改的左值是沒有數組類型的左值[...]
因此,由於數組不是可修改的左值,因此您無法分配給它們。 至於初始化部分6.7.8
初始化第14段說:
字符類型的數組可以由字符串文字[...]
在C++ 草案標准中,相關部分是4.2
Array-to-pointer conversion第1段,它說:
“NT 數組”或“T 的未知邊界數組”類型的左值或右值可以轉換為“指向 T 的指針”類型的純右值。 結果是指向數組第一個元素的指針。
prvalue是純右值,第5.17
節賦值和復合賦值運算符第1段說:
[...]都需要一個可修改的左值作為它們的左操作數[...]
讓我將程序簡化為:
char a[] = "Sunstroke";
char *b = a;
假設a
的地址是100,那么在內存中,它看起來是這樣的(僅說明指針大小和字節序等可能會有所不同):
[S] [u] [n] [s] [t] [r] [o] [k] [e] [\0] ... [0] [0] [0] [100]
100 101 102 103 104 105 106 107 108 109 200
^ ^
| |
a b
只要數組的生命周期, a
永遠是同一個地方,你不能修改它。
b
,另一方面,是一個包含數組地址的指針,你可以修改b
的值指向其他地方。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.