我是 C 編程新手。我知道 char * 和 char[] 陣列是不同的。但是,當涉及到函式引數時,您可以將 char[] 減去 char *。所以函式宣告可能是相同的。但是我如何通過查看簽名(宣告)來知道該函式是否特別期望一個 char 陣列而不是 char *?例如,如果我正在使用庫頭檔案并且函式如下。我怎么知道要通過哪一個?因為如果函式正在修改 bar 引數并且如果我傳遞一個 char *,它將得到一個段錯誤。這是針對 c 的,但是對于 c 是否也一樣?
somelib.h void foo(char *bar);
uj5u.com熱心網友回復:
如果函式修改了陣列,則應宣告引數char *。如果它不修改陣列,則應宣告引數const char *。
宣告引數時const char *,傳遞字串文字將是安全的。否則,您應該將陣列或指標傳遞給使用malloc()(在 C 中)或new(在 C 中)動態分配的記憶體。
在 C 中,如果您嘗試將文字傳遞給不帶const修飾符的引數,則會出現編譯錯誤,因為字串文字是const. 但是由于歷史原因,C 中字串文字的型別是 non- const,即使修改它們會導致未定義的行為,所以沒有錯誤(但某些編譯器會產生警告)。
uj5u.com熱心網友回復:
作為函式引數
我知道
char *和char[]陣列不同
雖然char *和char[]是不同的型別,但它們作為函式和函式引數并沒有什么不同,因為所有宣告為陣列的函式引數都被調整為指向該陣列元素的指標。因此,char[]編譯器將函式引數調整為char *. 此調整僅適用于函式引數,不適用于其他背景關系。
但是我如何通過查看簽名(宣告)來知道該函式是否特別期望一個 char 陣列而不是 char *?
需要 char 陣列的函式是需要char *. 我想你的意思是問如何知道函式是否期望/要求char *將指向陣列的元素。而且,也許陣列是否需要以空值結尾,或者具有最小大小。
答案是您無法僅通過查看簽名來知道它。
我怎么知道要通過哪一個?
通過閱讀描述函式作用的檔案。如果沒有檔案,請閱讀函式的實作。如果也沒有實作,那么您可以嘗試對二進制檔案進行逆向工程。如果您不知道該函式的作用,則不應呼叫它。
因為如果函式正在修改 bar 引數并且如果我傳遞一個 char *,它將得到一個段錯誤。
我想您的意思是該函式修改了指向的字符或字符。在這種情況下,修改指標本身應該沒問題。
如果其元素指向的陣列char *是可修改的,那么將其傳遞給修改陣列的函式不應導致段錯誤。如果陣列是 const,則不應將其傳遞給修改陣列的函式。
uj5u.com熱心網友回復:
您閱讀了檔案。如果沒有使用像 Agda 這樣的證明語言,型別系統將永遠無法完全描述函式的契約。在 C 中,閱讀檔案。
在 C 中,你永遠不應該使用char*. 期望字串的函式應采用std::string. 期望他們希望修改的字符的函式應該使用 a char&,并且在極少數情況下,您需要一個不是有效字串的字符陣列,std::vector<char>應該使用。在現代 C 中,從來沒有將原始指標用作公共函式引數的用例。
uj5u.com熱心網友回復:
當用作函式引數時,char *x完全char x[]等價。在許多其他情況下,它們不是。
對于描述為char *x(或char x[])的引數,函式不可能知道呼叫者實際傳遞了什么。呼叫者可能傳遞了一個陣列(作為指向該陣列第一個元素的指標傳遞)。它可能已經通過&vwhere vis a variable of type char。它可能已經通過了別的東西。
該函式所能做的就是做出一個假設,然后繼續這個假設。它可能會假設它傳遞了單個 的地址char,并且只修改它char。或者,它可能假設它已經傳遞了一個 1000 的陣列char,并修改所有這些字符。該函式可能假設(正如標準 C 字串函式在很多情況下所做的那樣)呼叫者傳遞了一個以 nul 結尾的陣列(一個可以具有任意長度的陣列,但結尾由一個char數值為零的哨兵標記) . 該函式可能會使用另一個引數來指定陣列的長度(因此請假設呼叫者同時傳遞了一個有效的陣列和一個正確的長度)。
不管它做了什么假設,如果呼叫者傳遞了與函式假設不同的東西,函式就有可能具有未定義的行為(例如訪問或覆寫不存在的字符)。
呼叫者(或試圖撰寫代碼來呼叫函式的程式員)的情況也是如此。只有兩種方法可以知道什么可以安全地傳遞給函式。
- 閱讀函式的檔案,并傳遞與檔案內容一致的內容。這樣做的風險(即使代碼中沒有錯誤)是程式員和代碼維護人員在保持函式檔案與函式實際所做的一致方面是出了名的糟糕——檔案可能會說一件事,但函式實際上做的是另一件事.
- 檢查函式的代碼。這是確定的,除非編譯器有錯誤并且錯誤地翻譯了代碼。更大的問題是,如果代碼復雜,可能需要花費大量精力來確定函式的作用并且容易出錯(對人類而言)。還有很多難以閱讀的代碼。
一些風格指南鼓勵函式的作者char *x將引數用于被視為單個地址的引數char,以及char x[]用于需要陣列的函式。對于編譯器來說,這沒有什么區別。許多程式員不遵守這樣的準則。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/473736.html
下一篇:有誰知道我的程式為什么會崩潰?
