函式設計
函式介面的兩個要素是引數和返回值。對於C++而言,引數和返回值的傳遞方式有三種,值傳遞,指標傳遞和引用傳遞。
引數規則
(1)引數的書寫要完整,不要貪圖省事只寫引數的型別而省略引數名字。如果沒有引數,則用void填充。
(2)引數命名要恰當,順序要合理。
(3)如果引數是指標,且僅作輸入用,則應在型別前加const,以防止該指標在函式體內被意外修改。
(4)如果輸入引數以值傳遞的方式傳遞物件,則宜改用“const &”方式來傳遞,這樣可以省略臨時物件的構造和析構過程,從而提高效率。
(5)避免函式有太多的引數,引數個數儘量控制在5個以內,如果引數太多,在使用時容易將引數型別或順序搞錯!
(6)儘量不要使用型別和數目不確定的引數。這種風格函式在編譯時喪失了嚴格的型別安全檢查。
返回值規則
(1)不要省略返回值的型別。C語言中凡不加型別說明的函式,一律自動按整形處理,這樣做不會有什麼好處,卻容易被誤解為void型別。C++語言是一門對型別極其苛刻,會有安全的檢查,不允許上述情況發生,由於C++程式可以呼叫C函式,為了避免混亂,規定任何C++/C函式都必須有型別。如果函式沒有返回值,那就應申明為void型別。
(2)函式名字與返回值型別在語義上不可衝突。
(3)不要將正常值和錯誤標誌混在一起返回,正常值用輸出引數獲得,而錯誤標誌用return語句返回。一般最好的處理方式將錯誤標誌位作為返回,而傳值用引數(指標形式)傳出。
(4)有時候函式原本不需要返回值,但為了增加靈活性如支援鏈式表達,可以附加返回值。
(5)如果函式返回值是一個物件,有些場合用引用傳遞替換值傳遞可以提高效率,而有些場合只能用值傳遞而不能用引用傳遞,否則會出錯。值傳遞需要額外的拷貝開銷。
函式內部實現的規則
不同功能的函式其內部實現各不相同,看起來似乎無法就“內部實現”達成一致的觀點,但根據經驗,我們可以在函式體的入口處和出口處從嚴把關,從而提高函式的質量。
(1)在函式體的入口處,對引數的有效性進行檢查。很多程式錯誤都是由非法引數引起的,我們應該充分理解並正確使用“斷言”assert來防止此類錯誤。
(2)在函式的出口處,對return語句的正確性和效率進行檢查。對於有返回值的函式,return寫得好與壞會影響函式的執行或效率。
<1>return語句不可返回指向“棧記憶體”的指標或者引用,因為該記憶體在函式體結束時被自動銷燬。
<2>要搞清楚返回的是值還是指標,還是引用。
<3>函式返回值是一個物件要考慮return語句的效率,最好採用引用返回,因為效率問題!!物件需要構造和析構,都需要時間!
(3)函式的功能要單一,不要設計多用途的函式。
(4)函式體的規模要小盡量控制在50行程式碼之內。
(5)儘量避免函式帶有記憶功能,相同的輸入產生相同的輸出。在C/C++語言中,函式static的區域性變數是函式的記憶儲存器,建議儘量少用static區域性變數,除非必須!
(6)不僅要檢查輸入引數的有效性,還要檢查通過其它用途進入函式體內的變數的有效性,如全域性變數、檔案控制程式碼等
(7)用於出錯處理的返回值一定要清楚,讓使用者不容易忽視或誤解錯誤情況。
使用斷言
程式一般分為debug和release版本,debug版本用於內部除錯,release版本發行給使用者使用。斷言assert是僅在debug版本起作用的巨集,它用於檢查不應該發生的情況。
assert不是一個倉促拼湊起來的巨集,為了不在程式的debug和release版本引起差別,assert不應該產生任何副作用。所以assert不是函式,而是巨集。程式設計師可以把assert看成一個在任何系統狀態下都可以安全使用的無害測試手段,如果程式在assert處終止了,並不是說含有該assert的函式有錯誤,而是呼叫者出了差錯,assert可以幫助我們找到發生錯誤的原因。
(1)使用斷言捕捉不應該發生的非法情況,不要混淆非法情況與錯誤情況之間的區別,後者是必然存在的並且是一定要作出處理的。
(2)函式入口處,使用斷言檢查引數的有效性(合法性)。
(3)編寫函式時,要進行反覆的考查,並且自問:我打算做哪些假定?一旦確定了的假定,就要使用斷言對假定進行檢查。
(4)當進行犯錯設計時,如果不可能發生的事情的確發生了,則要使用斷言進行報警!
相關文章
- 函式程式設計函式程式設計
- JavaScript 設計模式系列 – 自定義函式(惰性函式)JavaScript設計模式函式
- python函式程式設計 返回函式 匿名函式 裝飾器 偏函式Python函式程式設計
- JS 命令式 宣告式 函式式 程式設計?JS函式程式設計
- select函式socket程式設計函式程式設計
- 函式響應式程式設計與RxSwift函式程式設計Swift
- Python函數語言程式設計-高階函式、匿名函式、裝飾器、偏函式Python函數程式設計函式
- 瞭解 JavaScript 函數語言程式設計 - 宣告式函式JavaScript函數程式設計函式
- 設計包含min函式的棧函式
- Bash程式設計007——函式(一)程式設計函式
- SSD的損失函式設計函式
- 揚帆起航:從指令式程式設計到函式響應式程式設計程式設計函式
- 不用任何賦值的程式設計稱為*函式式*程式設計賦值程式設計函式
- Lambda表示式入門--函數語言程式設計與函式式介面函數程式設計函式
- Day 14 匿名函式 內建函式 物件導向程式設計函式物件程式設計
- 函數語言程式設計-鏈式程式設計RAC函數程式設計
- Python 函數語言程式設計 – 高階函式Python函數程式設計函式
- Python函數語言程式設計自帶函式Python函數程式設計函式
- 14-2 雜湊函式設計函式
- Ardunio和HAL庫函式程式設計函式程式設計
- JavaScript函數語言程式設計(純函式、柯里化以及組合函式)JavaScript函數程式設計函式
- 嵌入式軟體架構設計-函式呼叫架構函式
- 好程式設計師Python教程系列遞迴函式與匿名函式呼叫程式設計師Python遞迴函式
- Java中的函數語言程式設計(二)函式式介面Functional InterfaceJava函數程式設計函式Function
- Java程式設計基礎05——方法(函式)Java程式設計函式
- 【Linux網路程式設計】Socket Api函式Linux程式設計API函式
- 前端-JavaScript非同步程式設計async函式前端JavaScript非同步程式設計函式
- 函數語言程式設計:Lambda 表示式函數程式設計
- .NET併發程式設計-函式閉包程式設計函式
- Python基礎程式設計(十六)——函式4Python程式設計函式
- 好程式設計師Python培訓分享函數語言程式設計之匿名函式程式設計師Python函數函式
- 從函數語言程式設計到Ramda函式庫(一)函數程式設計函式
- [靈性程式設計]函式委託,自動事件,函式觀察者(golang)程式設計函式事件Golang
- PHP函式漏洞審計之addslashes函式-PHP函式
- java8函數語言程式設計筆記-破壞式更新和函式式更新Java函數程式設計筆記函式
- scala簡明教程:偏函式、高階函式、Future非同步程式設計、隱式轉換函式非同步程式設計
- JavaScript函數語言程式設計之pointfree與宣告式程式設計JavaScript函數程式設計
- Shell程式設計-09-Shell中的函式程式設計函式