#include<stdio.h>
void main(){
char *a="hahaha hahaha";
printf("%s\n", a);
*(a + 6) = '1';
a[7] = '2';
printf("%s\n", a);
}
這段程式,功能是給a[6] a[7] 賦值成字符1 2
編譯不報錯,運行結果如下:
hahaha hahaha
段錯誤(核心已轉儲)
將指標換成一維陣列就不會有這種問題
求大佬告訴我這是為什么
uj5u.com熱心網友回復:
這樣定義的字串其實隱藏了一個條件const,即只讀字符陣列,倒不是不可以改,只是你這樣的方式不能修改uj5u.com熱心網友回復:
那該如何修改呢,請說。。uj5u.com熱心網友回復:
錯了,這個應該是常量的,也就是這個指標指向了記憶體的常量區,不可修改,如果使用const修飾字符陣列,是存在變數區的,可以用指標修改
#include <stdio.h>
int main() {
const char s[] = "hello";
char *p = &s;
*(p + 2) = 'c';
printf("%s", s);
return 0;
}
uj5u.com熱心網友回復:
你可以測驗一下printf("%p\n", a);
printf("%p\n", "hahaha hahaha");
你會發現兩者是同一地址。
"hahaha hahaha"叫什么字面量,存盤的位置和變數是不同。
該位置不可更改
uj5u.com熱心網友回復:
char s[] = "hello";這個s,同樣不可更改,不能使用指標操作,只能使用下標。
char *p = s;
這樣就可以了,因為p是變數,而s是常量。
uj5u.com熱心網友回復:
樓上2位的回答真是一言難盡我一個一個糾正吧
用指標修改const限定的陣列是 未定義行為
錯誤的做法
后面的代碼也存在錯誤
char *p = &s;
&s 型別是 const char(*)[6]
不匹配char* 是錯誤的做法
目測C里面會有一個警告 C++應該直接報錯
printf("%s", s);輸出的可能是原來的
而不是你預期的
不做這樣的保證 a可以和后面的"hahaha hahaha" 占用不同的地址
并且有沒有占用相同地址 和 題主的問題無關
uj5u.com熱心網友回復:
事實勝于雄辯,不能正常運行絕不會亂說,你自己去試試吧
uj5u.com熱心網友回復:
樓上2位的回答真是一言難盡
我一個一個糾正吧
如果使用const修飾字符陣列,是存在變數區的,可以用指標修改
用指標修改const限定的陣列是 未定義行為
錯誤的做法
后面的代碼也存在錯誤
char *p = &s;
&s 型別是 const char(*)[6]
不匹配char* 是錯誤的做法
目測C里面會有一個警告 C++應該直接報錯
printf("%s", s);
輸出的可能是原來的
hello
而不是你預期的 heclo
你可以測驗一下
printf("%p\n", a);
printf("%p\n", "hahaha hahaha");
你會發現兩者是同一地址。
"hahaha hahaha"叫什么字面量,存盤的位置和變數是不同。
該位置不可更改
不做這樣的保證 a可以和后面的"hahaha hahaha" 占用不同的地址
并且有沒有占用相同地址 和 題主的問題無關
事實勝于雄辯,不能正常運行絕不會亂說,你自己去試試吧
抱歉,沒看清你說的,那個&純屬多余,寫錯了
uj5u.com熱心網友回復:
事實勝于雄辯,不能正常運行絕不會亂說,你自己去試試吧
請問 我哪一行說了 可以正常運行?
我說的是 你的代碼可能輸出的是修改前的結果
而不是你預期的修改后的結果
uj5u.com熱心網友回復:
事實勝于雄辯,不能正常運行絕不會亂說,你自己去試試吧
請問 我哪一行說了 可以正常運行?
我說的是 你的代碼可能輸出的是修改前的結果
而不是你預期的修改后的結果
應該有個警告的,打的時候錯輸入,似乎沒顯示,沒看見,你說的沒錯
uj5u.com熱心網友回復:
樓上2位的回答真是一言難盡
我一個一個糾正吧
如果使用const修飾字符陣列,是存在變數區的,可以用指標修改
用指標修改const限定的陣列是 未定義行為
錯誤的做法
后面的代碼也存在錯誤
char *p = &s;
&s 型別是 const char(*)[6]
不匹配char* 是錯誤的做法
目測C里面會有一個警告 C++應該直接報錯
printf("%s", s);
輸出的可能是原來的
hello
而不是你預期的 heclo
你可以測驗一下
printf("%p\n", a);
printf("%p\n", "hahaha hahaha");
你會發現兩者是同一地址。
"hahaha hahaha"叫什么字面量,存盤的位置和變數是不同。
該位置不可更改
不做這樣的保證 a可以和后面的"hahaha hahaha" 占用不同的地址
并且有沒有占用相同地址 和 題主的問題無關
這個是不會錯的,我學習的時候專門測驗過。
全域變數,區域變數,和這個字符字面量是保存在記憶體不同區域的。
這個位置的都是常量,不可修改。
事實勝于雄辯,不能正常運行絕不會亂說,你自己去試試吧
uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
uj5u.com熱心網友回復:

好吧,我也不知道了。反正這里不讓賦值。
uj5u.com熱心網友回復:
好吧,我也不知道了。反正這里不讓賦值。
這里的確不能賦值
但是 和你說的地址一樣 沒什么關系
uj5u.com熱心網友回復:
好吧,我也不知道了。反正這里不讓賦值。
這里的確不能賦值
但是 和你說的地址一樣 沒什么關系
有關系的吧,C/C++程式編譯后幾個不同區的地址范圍是不一樣的。可以通過地址推測這個地址是屬于什么區的變數。
這個問題我的理解是,這個地址會落在常量區,常量區的內容是不允許修改的,所以就報錯了。
修改的方法是強行把常量區的內容放到堆疊區,像這樣char a[]="hahaha hahaha";
雖然“hahaha hahaha”還是會存盤在常量區,但陣列的初始化賦值操作會將常量區的內容復制出來,放在堆疊區,陣列a指向這塊堆疊區。
有興趣的話可以讀一下這篇博文,很短。
uj5u.com熱心網友回復:
另外通過void main的寫法,樓主肯定還是學生。建議以后不要這么寫了。。。十幾二十年過去了,譚浩強荼毒至今啊。。哎
uj5u.com熱心網友回復:
好吧,我也不知道了。反正這里不讓賦值。
這里的確不能賦值
但是 和你說的地址一樣 沒什么關系
有關系的吧,C/C++程式編譯后幾個不同區的地址范圍是不一樣的。可以通過地址推測這個地址是屬于什么區的變數。
這個問題我的理解是,這個地址會落在常量區,常量區的內容是不允許修改的,所以就報錯了。
修改的方法是強行把常量區的內容放到堆疊區,像這樣char a[]="hahaha hahaha";
雖然“hahaha hahaha”還是會存盤在常量區,但陣列的初始化賦值操作會將常量區的內容復制出來,放在堆疊區,陣列a指向這塊堆疊區。
有興趣的話可以讀一下這篇博文,很短。

你說的我都懂
我說的你沒懂
這是一個邏輯理解的問題
2個字串是同一個地址 不能用于說明 字串處于常量區
是不是處于常量區 應該分析 這個地址和.rdata段的關系
uj5u.com熱心網友回復:
好吧,我也不知道了。反正這里不讓賦值。
這里的確不能賦值
但是 和你說的地址一樣 沒什么關系
有關系的吧,C/C++程式編譯后幾個不同區的地址范圍是不一樣的。可以通過地址推測這個地址是屬于什么區的變數。
這個問題我的理解是,這個地址會落在常量區,常量區的內容是不允許修改的,所以就報錯了。
修改的方法是強行把常量區的內容放到堆疊區,像這樣char a[]="hahaha hahaha";
雖然“hahaha hahaha”還是會存盤在常量區,但陣列的初始化賦值操作會將常量區的內容復制出來,放在堆疊區,陣列a指向這塊堆疊區。
有興趣的話可以讀一下這篇博文,很短。
你說的我都懂
我說的你沒懂
這是一個邏輯理解的問題
2個字串是同一個地址 不能用于說明 字串處于常量區
是不是處于常量區 應該分析 這個地址和.rdata段的關系
對于一個已經編譯好的C/C++程式,各區的地址范圍應該已經確定了。根據地址肯定可以知道變數的存盤區域啊。
有disassembly檔案當然最好,但是沒必要這么麻煩
uj5u.com熱心網友回復:
對于一個已經編譯好的C/C++程式,各區的地址范圍應該已經確定了。根據地址肯定可以知道變數的存盤區域啊。
有disassembly檔案當然最好,但是沒必要這么麻煩
所以呢 說半天你說的我都知道 并且和我說的一樣
你想表達什么呢?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/130849.html
標籤:非技術區
上一篇:有沒有大佬知道烏班圖18下進行c語言編譯,提示缺少頭檔案的問題怎么解決呀?
下一篇:c語言小白 求解題
