最近我拿到了一本 C 程式設計語言書。在第 95 頁上有一個 strcpy 函式的實作。
void strcopy(char *s, char *t) {
while(*s = *t )
;
}
int main(int argc, char *argv[]) {
char *hello = "hello";
char *world = "world";
strcopy(hello, world);
return 0;
}
我試圖自己實作它,但在(成功)編譯之后
gcc -o c_lang c_programming_lang_exercises.c
并嘗試運行它
./c_lang
我收到以下錯誤訊息:
zsh: bus error
我用不同的實作嘗試了它,但不知何故這對我不起作用。
也許有人知道為什么?
感謝您的幫助 :)
編輯:根據我自己的理解,如果我錯了,請糾正我。在函式呼叫中“strcopy(hello, world);” 我在這里傳遞指標本身的值,所以我用這樣的東西呼叫函式:strcopy(0x123a4, 0x234859b)。現在 C 不認為這是變數,因此它的值被復制并傳遞給函式。在 strcopy 函式本身中,我無法取消參考它,因為我只是獲得了指標的值。
我應該做的是傳遞地址,指標參考,以便我可以取消參考 strcopy 函式中的值并訪問正確的記憶體地址。
另一個錯誤可能是在我宣告的主函式char *hello = "hello"中,據我所知,它被稱為字串常量,因此不可修改。
所以,如果我的假設是正確的,下面的代碼應該可以作業:
void strcopy(char *s, char *t) {
//code goes here...
}
int main(int stringc, char *argv[]) {
char hello[] = "hello";
char world[] = "world";
strcopy(&hello, &world);
return 0;
}
它有效,但我收到以下編譯器警告:
incompatible pointer types passing 'char (*)[6]' to parameter of type 'char **' [-Wincompatible-pointer-types]
strcopy(&hello, &world);
uj5u.com熱心網友回復:
C 在型別方面做出了非常糟糕的讓步,這與歷史原因有關。
在 中main(),您將字串宣告為:
char *hello = "hello";
您應該做的是調高警告級別waaaay并重新編譯。問題是這"hello"是一個字串文字——它不能被修改。它應該宣告為:
const char *hello = "hello";
(打開警告會告訴你這一點。)
因此,您試圖將字符復制到只讀記憶體中,這在現代處理器和現代編譯器上是不允許的——它會產生訪問沖突。Zsh為你抱怨。
相反,請確保您對從只讀記憶體復制的本地陣列具有寫訪問權限:
char hello[] = "hello";
是的,這會生成一個長度為 6 個字符的本地可變陣列(“hello”一詞為 5 個字符,空終止符為 1 個字符),并從只讀存盤器自動初始化。
這是在 C 中宣告事物的微妙癥結之一,經常使初學者感到困惑:
const char * s = "Hello world!";— 指向 ROM 的指標char s[] = "Hello world!";— 從 ROM 初始化的本地可變陣列
就是這樣!
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/356274.html
上一篇:如何在C中解決這個指標回圈?
