c語言中的字符串充蓝,我在以前都一直以為是常量(自己學習不精)君躺,實際上字符串在賦值給char*的時候是系統(tǒng)現(xiàn)在內存中開辟一段空間犹撒,把字符串的內容存入內存中横腿,再把地址賦給char *颓屑。
例如這樣:
程序段:
程序運行結果:
解釋:
我們通過定義了一個變量斤寂,例如:int a; 實際上是系統(tǒng)為程序開辟了一段屬于變量 a 的內存空間,假設內存地址為aaaaa揪惦。我們改變 a的值遍搞,比如 本來a=5; 實際上是向內存中的地址為aaaaa的內存空間存入了5的數(shù)值,后來的程序句中變成 a=6; 實際上是把內存中的地址為aaaaa的內存空間中存有的5改成了6器腋。我通過指針int *b=&a;
將b指向a后溪猿,通過*b=6
,來改變a纫塌,實際上a也等于6诊县,實際上也就是aaaaa內存空間的5變成了6。
這時候問題來了护戳,既然字符串在出現(xiàn)的時候會讓系統(tǒng)開辟內存空間并且將字符串的數(shù)值存入這個內存空間翎冲,那我是否能夠通過指針來改變這一段內存空間的內容呢?
如果是普通的
char *a="abcd";
a="bcde";
這樣的話媳荒,也就是先把a指向"abcd"然后再把a指向"bcde"而已了抗悍。
但是我想這樣:
char *a="abcd";
*a="bcde";
呢?
答案是不行钳枕,編譯器不會報編譯錯誤缴渊,但是在程序運行的時候就會出錯。
程序運行到*a="bcde"; 時就卡住鱼炒,然后非正常退出了衔沼。
也就是我們無法通過 向*a賦值一個字符串 這種方式來改變原本存有"abcd"的那一段內存中的內容。
但是書上說到了:
可以通過改變字符串中的一個字符昔瞧,并且不通過*pl輸出指蚁,通過直接輸出"Klingon"(因為"Klingon"就代表了它所在的那一段內存,就像int a中的變量a代表了a所在的那一段內存) 看到原本的"Klingon" 變成了"Flingon"自晰,也就是內存中連續(xù)存放著的'K''l''i''n''g''o''n'中的'K'被改變成了'F'凝化,變成了'F''l''i''n''g''o''n'。書上也說明了:"實際上在過去酬荞,一些編譯器由于這方面的原因搓劫,其行為難以捉摸,而另一些編譯器則導致程序異常中斷混巧。"
當我調用"Klingon"這個字符串時候枪向,全局程序都會使用同一個內存中的字符串。如果你通過某個指針上改變了"Klingon"的值咧党,也就是改變了"Klingon"這個字符串內存中的數(shù)值秘蛔,會使得之后的程序調用"Klingon"字符串時,會變成"Flingon"或者是其他的什么。所以系統(tǒng)保護字符串常量不能被修改缠犀。
通過書上的例子進行修改:
結果:
直接用指針修改會導致 Segmentation fault 錯誤数苫,對內存的錯誤訪問
應該是字符串被當做常量,存放在內存常量區(qū)由系統(tǒng)保護辨液,所以無法改變