簡體   English   中英

為什么我們不能將新字符串分配給 char 數組,而是分配給指針?

[英]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之外)。

如果您需要操作字符串,則:

  • 在 C 中,您需要仔細創建足夠大的數組以滿足您的需要,並使用<string.h>的庫函數(或您自己編寫的代碼)來操作這些數組中的字符;
  • 在 C++ 中,使用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 conversion1段,它說:

“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.

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