據我所知,不能修改字串文字,例如:
char* a = "abc";
a[0] = 'c';
那是行不通的,因為字串文字是只讀的。我只能在以下情況下修改它:
char a[] = "abc";
a[0] = 'c';
但是,在這篇文章中, 決議 $PATH 變數并將目錄名稱保存到字串陣列中,第一個答案在這兩個地方修改了字串文字:
path_var[j]='\0';
array[current_colon] = path_var j 1;
我對C不是很熟悉,所以任何解釋都將不勝感激。
uj5u.com熱心網友回復:
在編程中,有很多規則需要你遵守,即使它們不是——必須——強制執行。而“C 中的字串文字不可修改”就是其中之一。getenv
“不應修改回傳的字串”也是如此。
有一些適用于現實世界的類比。這是一個:如果您在十字路口,并且燈是紅色的,則您不應該過馬路。但是,很多時候,如果你違反規則并越界,你可能會僥幸逃脫。你可能會從警察那里得到一張罰單——或者你可能不會。你可能會導致崩潰——或者你可能不會。但如果你很幸運,這些事情都沒有發生,這并不意味著闖紅燈是可以的——這仍然是非常違反規則的。
同樣,在 C 中,如果您撰寫一些代碼來修改字串文字或從 . 回傳的字串getenv
,您可能會僥幸逃脫。編譯器可能會給你一個警告或錯誤訊息——或者它可能不會。你的程式可能會崩潰——也可能不會。但是,如果該程式似乎可以作業,那并不意味著這些字串實際上是可修改的——它們不是。
uj5u.com熱心網友回復:
在示例中
char* a = "abc";
該標記"abc"
在程式映像中產生一個文字物件,并表示一個產生該物件地址的運算式。
在示例中
char a[] = "abc";
令牌"abc"
用作陣列初始值設定項,并不表示文字物件。它相當于:
char a[] = { 'a', 'b', 'c', 0 };
的單個字符值"abc"
是文字資料以某種方式記錄在程式映像中的某處,但它們不能作為字串文字物件訪問。
不用說,陣列a
不是文字。修改a
不構成修改文字,因為它不是一個。
關于備注:
那是行不通的,因為字串文字是只讀的。
那是不準確的。ISO C 標準(目前還沒有它的版本)沒有規定如果程式試圖修改字串文字會發生什么要求。這是未定義的行為。如果您的實作使用一些診斷訊息停止程式,那是因為未定義的行為,而不是因為它是必需的。
C 實作不需要支持字串文字修改,它具有以下好處:
符合標準的 C 程式可以翻譯成可以燒入 ROM 芯片的映像,這樣就可以直接從該 ROM 映像訪問它們的字串文字,而不必在啟動時將其復制到 RAM 中。
編譯器可以利用一種文字是另一種文字的后綴的情況來壓縮字串文字的存盤。運算式
"string" 2 == "ring"
可以產生真值。由于嚴格遵守的程式不會做類似的事情,因為那是未定義的行為,因此這樣的程式將避免成為意外變成的意外"ring"[0] = 'w'
的受害者。"string"
"stwing"
uj5u.com熱心網友回復:
您鏈接的帖子中的代碼塊:
const char *orig_path_var = getenv("PATH");
char *path_var = strdup(orig_path_var ? orig_path_var : "");
const char **array;
array = malloc((nb_colons 1) * sizeof(*array));
array[0] = path_var;
array[current_colon] = path_var j 1;
第一塊:
- 在第一行
getenv()
中,回傳一個指向由 指向的字串的指標orig_path_var
。回傳的字串get_env()
應被視為只讀字串,因為如果程式嘗試修改它,則行為未定義。 - 在第 2 行
strdup()
中呼叫以復制此字串。這樣strdup()
做的方法是呼叫malloc()
并為字串的大小分配記憶體 1,然后將字串復制到記憶體中。 - 由于
malloc()
使用,字串存盤在堆上,這允許我們編輯字串并修改它。
第二塊:
- 在第一行中,我們可以看到它
array
指向一個char *
指標陣列。陣列中有nb_colons 1
指標。 - 然后在第 2 行中,第 0 個元素
array
被初始化為path_var
(記住它不是字串文字,而是一個的副本)。 - 在第 3 行中,將 的
current_colon
第 th 個元素array
設定為path_var j 1
。如果您不了解指標運算,這僅意味著它將j 1
第 char的地址分配給path_var
toarray[current_colon]
。
如您所見,代碼沒有在const
字串文字上運行,例如orig_path_var
. 相反,它使用用strdup()
. 這似乎是你困惑的根源,所以看看這個:
char *strdup(const char *s);
strdup() 函式回傳一個指向新字串的指標,該字串是字串 s 的副本。新字串的記憶體使用 malloc(3) 獲得,并且可以使用 free(3) 釋放。
上面的文本顯示了strdup()
根據其手冊頁所做的操作。
閱讀手冊頁也可能會有所幫助。malloc()
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/506449.html