Re: [問題] 字元指標的問題

看板C_and_CPP (C/C++)作者 (髮箍)時間6年前 (2019/09/06 23:11), 6年前編輯推噓3(3010)
留言13則, 3人參與, 6年前最新討論串2/4 (看更多)
這裡給的錯誤訊息不明確, 推文中提到的型別檢查變嚴格也不是原 . 在講原因前先來瞭解賦値/初始化敘述最重要的幾個要素: B = A; 當我們要把 A 賦値給 B 的時候, 至少需要弄清楚以下 3 點: 1. A 的型別為何? 2. B 的型別為何? 3. 可不可以透過隱式轉換 (implicit conversion) 將 A 的型別轉換到B 的型別? 簡單舉個例子, 我們都知道以下的程式碼是合法的: int i = 0; int* pi = &i; // 1. pi's type is int* void* pv = pi; // 2. pv's type is void* // 3. valid, convert int* to void* 再回到原本的問題: char* str = "hello"; 在將 string literal 給 char* 物件做初始化之前, 你需要知道它 的型別是什麼, 據我所知在 C 和 C++ 內定義的型別不同: C (n2346) https://bit.ly/2lHYvLe 6.4.5.6 The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence. C++ (n4830) https://bit.ly/2k3F5jL 5.13.5.6 An ordinary string literal has type “array of n const char” where n is the size of the string as defined below, has static storage duration, and is initialized with the given characters. 所以你的程式碼效果其實和下面的差不多 (C++): const char literal[6] = {'h', 'e', 'l', 'l', 'o', '\0'}; char* str = literal; 會有錯誤的原因在這: 透過隱式轉換無法將指標的 constness 給移除. 還有另外一個地方需要注意: 因為 string literal 本身是陣列, 陣列賦値/計算之前會先退化 (decay) 成指標 (也是轉型的一種), 錯誤訊息省略描述這個步驟所以很容易讓人誤解它的型別. 最後總 結一下編譯器做的事情: 1. 取得 "hello" 的型別, 為 const char[6] 2. 因為要賦値, 把 "hello" 陣列退化成 const char* 3. 取得 str 的型別, 為 char* 4. 檢查能否透過隱式轉換將 const char* 轉成 char* (失敗) 第一個步驟 C 和 C++ 編譯器取得的型別相異, 導致結果也不同, 這也是常常拿網路上的原始碼會編不過的原因, 其實 C 和 C++ 是 兩個 (只有) 語法相似但本質不同的語言. -- P1389R0: Guidelines for Teaching C++ to Beginners https://bit.ly/2GvDWKb SG20 Education and Recommended Videos for Teaching C++ https://www.cjdb.com.au/sg20-and-videos -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.193.76.216 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1567782670.A.03A.html ※ 編輯: poyenc (123.193.76.216 臺灣), 09/07/2019 03:23:11

09/07 09:42, 6年前 , 1F
小弟認為隱轉跟字串常數的建立是兩回事的, 因為用顯轉就
09/07 09:42, 1F

09/07 09:42, 6年前 , 2F
可解決。原po的問題我過去的記憶不曾遇到, 加上小弟最近
09/07 09:42, 2F

09/07 09:42, 6年前 , 3F
在寫c#(碰到不給隱轉成parent class), 所以認為vs是朝向s
09/07 09:42, 3F

09/07 09:42, 6年前 , 4F
trong type checking一派的。而且原po的code來源因使用io
09/07 09:42, 4F

09/07 09:42, 6年前 , 5F
stream所以應為c++,(用.c丟給gcc/g++不給過) ,再來字串
09/07 09:42, 5F

09/07 09:42, 6年前 , 6F
常數的隱轉問題用gcc與g++及使用c++17都只有warning, 所
09/07 09:42, 6F

09/07 09:42, 6年前 , 7F
以我覺得問題只是微軟走嚴格趨勢
09/07 09:42, 7F

09/07 12:18, 6年前 , 8F
樓上怎麼會有因為「只有 warning」所以程式碼「不是
09/07 12:18, 8F

09/07 12:19, 6年前 , 9F
ill-formed」的結論?
09/07 12:19, 9F

09/07 17:47, 6年前 , 10F
因為只是要回答原po問的教學文章貼上卻會報錯的問題出在
09/07 17:47, 10F

09/07 17:47, 6年前 , 11F
編譯器差別不是語法或c/c++的差別。code本質對錯就看此篇
09/07 17:47, 11F

09/07 17:47, 6年前 , 12F
樓主就行了
09/07 17:47, 12F

09/07 22:21, 6年前 , 13F
感謝回答
09/07 22:21, 13F
文章代碼(AID): #1TSdSE0w (C_and_CPP)
文章代碼(AID): #1TSdSE0w (C_and_CPP)