看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《david830317 (dd810)》之銘言: : 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) : Xcode : 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) : 問題(Question): : 在xcode時用void以外不能用reture : 錯誤結果(Wrong Output): : Control may reach end of non-void function : 程式碼(Code):(請善用置底文網頁, 記得排版) : http://ideone.com/T36LJH : 補充說明(Supplement): 關於這個 function 的寫法 float Quantity::calcValue() const { if (unit >= 1 && unit <= 10) { return unit * 3.00; } if (unit >= 11 && unit <= 50) { return unit * 2.50; } if (unit >= 51) { return unit * 2.00; } } 我比較建議用 if-elseif-elseif 的結構來寫: float Quantity::calcValue() const { if (unit >= 1.0f && unit <= 10.0f) { return unit * 3.00f; } else if (unit > 1.0f && unit <= 50.0f) { return unit * 2.50f; } else if (unit >= 50.0f) { return unit * 2.00f; } else { /* default */ return unit; } /* Unreached */ } 原因: 1. 這樣才看得清楚這三條 if 其實是負責同一件事,條件排列整齊後,漏網之魚也 在 default 那一區塊有處理,不管是 error handling 還是 return default, 而且所有的狀況在 if-else 結構內都會 return,能輕易判斷函式終結點。 2. float 運算時,不管是比大小還是運算,最好兩邊都是 float (10.0f), 你有些寫 int,問題倒還不大反正會轉成 float,但有些寫 double (2.50) 就 會兩邊都轉成 double 運算,運算完再轉 float 再 return,浪費效能。 另一個問題點,你大概一開始把 unit 定義為 int 後來才改 float, 所以 if 裡面完全沒有處理到 10.0f<unit<11.0f, 50.0f<unit<51.0f 的狀況, 如果習慣把常數的 data type 也寫對,遇到可能有問題的狀況,心中自然會產生 違和感,覺得這樣寫怪怪的。你寫 10.0f 時就會考慮 10.5f 會發生什麼事 3. 最後註解 Unreached 其實很有必要,照我的寫法所有狀況都應該在 if-else 的 結構內 return,所以不會跑到 Unreached 那邊。但就是有些人在修改 code 時 會呆呆加在後面,以為 if 跑完就會跑他加的東西,所以要註解提醒。 實務上有很多地方需要這樣的防呆措施,不只是合作寫程式防別人耍呆,很多 時候自己也會發蠢, * * * 舉另一個經典例子: if (unit > 1.0f) return unit*3.0f; 這樣寫在 C/C++ 是允許的,省略大括號。但是就有人這樣插一行... if (unit > 1.0f) printf("Using 3.0 ratio.\n"); return unit*3.0f; 結果變成不管 unit 值多少,有沒有 print 那行字,都變成 return unit*3.0f 了 所以我會嚴格要求如果 if 的內容分成兩行寫,一定要加大括號 if (unit > 1.0f) { return unit*3.0f; } 或這樣也行 if (unit > 1.0f) { return unit*3.0f; } 寫成同一行的話隨便你加不加 if (unit > 1.0f) return unit*3.0f; 大家應該會覺得是插入新行卻不長眼看清楚的那個人的錯,我也覺得是他的錯, 但是這種狀況實在太多太多了,大家都是用 Ctrl-C & Ctrl-V 在寫程式的樣子, 熬夜拼命貼的時候就常常貼錯地方,只好設法定一些規則防呆。 這樣至少你 code review 時就可以檢查大括號來預防出錯,而不是每次 release 的 前一天晚上才在抓幾百個這種無腦錯誤。 -- 桃樂絲: 可是, 如果你沒有頭腦, 為什麼會說話? 稻草人: ㄝ, 我也不知... 但是有些人沒有頭腦也能說超~多話呢。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 1.164.198.178 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1461828217.A.029.html
MOONRAKER: else if 不錯,清楚要求只有一個case執行 04/28 15:55
MOONRAKER: 也有人要求很長很大的if block不要用else 04/28 15:55
MOONRAKER: 而是要 if (flag) { ... } if (!flag) { ... } 的 04/28 15:55
MOONRAKER: 不過那是另外一回事情 04/28 15:56
james732: 推 04/28 20:11
CoNsTaR: 用 monads 來寫最方便啦 XDD 04/29 12:42
bibo9901: monad是個糟糕的設計 04/29 13:09
CoNsTaR: 是啊 它隱藏了不該隱藏的細節 可是就是方便嘛 XDD 04/29 13:13
bibo9901: C又沒有綁手綁腳的"純"函數 跟本不必用monad啊 04/29 13:15
chen20: 推推 04/29 21:59
david830317: 我是原PO謝謝大大的建議跟詳細的講解!! 05/23 13:12