如果我通過以下方式初始化幾個字串(字符陣列)變數:
const char* myString1 = "string content 1";
const char* myString2 = "string content 2";
由于const char*只是一個特定char物件的指標,它不包含它所指向的字符陣列的任何大小或范圍資訊。
那么,兩個字串文字是否可能相互重疊?(新分配的與舊的重疊)
通過重疊,我的意思是以下行為;
// Continue from the code block above
std::cout << myString1 << std::endl;
std::cout << myString2 << std::endl;
它輸出
string costring content 2
string content 2
所以開始myString2是在中間的某個地方myString1。因為const char*不會“保護”(“擁有”)一系列記憶體位置,而只是它指向的那個,我看不出 C 如何防止其他字串文字“降落”在舊字串的記憶體位置上。
C /編譯器如何避免這樣的問題?
如果我更改const char*為const char[],它是否仍然相同?
uj5u.com熱心網友回復:
是的,通常允許字串文字重疊。來自lex.string#9
...是否所有字串文字都是不同的(即存盤在非重疊物件中)以及字串文字的連續計算是否產生相同或不同的物件是未指定的。
因此,由編譯器決定是否有任何字串文字在記憶體中重疊。您可以撰寫一個程式來檢查字串文字是否重疊,但由于未指定是否發生這種情況,因此每次運行該程式時您可能會得到不同的結果。
uj5u.com熱心網友回復:
字串必須以值為 0 的空字符結尾,并且中間不能有這樣的字符。因此,唯一可能的情況是當兩個字串從一個字串的開頭到兩個字串的結尾相等時。在您給出的示例中情況并非如此,因此這兩個特定字串永遠不會重疊。
編輯:對不起,我不是有意誤導任何人。使用\0.在字串中間放置一個空字符實際上很容易。但是大多數字串處理函式,尤其是標準庫中的函式,會將其視為字串的結尾——因此您的字串將被截斷。不是很實用。因此,除非您明確要求,否則編譯器不會嘗試構造這樣的字串。
uj5u.com熱心網友回復:
編譯器知道每個字串的大小,因為它可以在您的代碼中“看到”它。
此外,它們的分配方式與您在運行時分配的方式不同。相反,如果字串是常量并且是全域定義的,那么它們很可能位于.text目標檔案的部分,而不是堆中。
并且由于編譯器在編譯時知道常量字串的大小,因此它可以簡單地將其值放在該.text節的空閑空間中。具體取決于您使用的編譯器,但請放心,撰寫代碼的人足夠聰明,可以避免此問題。
如果您在某個函式中定義這些字串,則編譯器可以在第一個選項和在堆疊上分配空間之間進行選擇。
至于const char[],大多數編譯器會以與const char*.
uj5u.com熱心網友回復:
除非相同,否則兩個字串文字不太可能重疊。在這種情況下,盡管指標將指向同一事物。(雖然標準并不能保證這一點,但我相信任何現代編譯器都應該做到這一點。)
const char *a = "Hello there."
const char *b = "Hello there."
cout << (a == b);
// prints "1" which means they point to the same thing
雖然const char *可以共享一個字串。
const char *a = "Hello there.";
const char *b = a 6;
cout << a;
// prints "Hello there."
cout << b;
// prints "there."
我認為要回答您的第二個問題,對 c 樣式字串的解釋很有用。
Aconst char *只是一個指向字串的指標。const 意味著字符本身是不可變的。(它們作為可執行檔案本身的一部分存盤,您不希望您的程式像這樣改變自己。您可以使用stringsunix 上的命令輕松strings a.out查看可執行檔案中的所有字串,即。您會看到比什么更多的字串您編碼了許多作為標準庫的一部分存在的可執行檔案所需的其他內容。)
那么它怎么知道只列印字串然后在最后停止呢?好吧,c 樣式的字串需要以空位元組 ( \0)結尾。當你宣告一個字串時,編譯器隱式地把它放在那里。"string content 1"實際上也是如此"string content 1\0"。
const char *a = "Hello\0 there.";
cout << a;
// prints "Hello"
大多數情況下const char *a和const char a[]是一樣的。
// These are valid and equivalent
const char *a = "Hello";
const char b[] = "there."
// This is valid
const char *c = b 3; // *c = "re."
// This, however, is not valid
const char d[] = b 3;
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/366753.html
