程式語言必須養成良好的習慣,不然當大型Code的時候,您會發現一堆不知道幹嘛的變數,和一堆不知道幹嘛的函式,最後導致您要reuse一些函式你要找半天,或者找變數找錯(例如您要找aaa函數,結果找到bbb,會混亂拉)
這裡其實我也沒完全都很遵守下面我提到的這些,但是當案子寫大後,您其實按照這個邏輯去做命名或者擺放你的Code會變得比較好查程式碼(因為IDE都有文件搜尋功能)
最簡單來說就是做有意義的命名
基本上您可以想做是你在寫專案
要是您無聊寫個小程式,下次就不改了,其實就隨便拉
其實就是直觀,不管你用任何語言都一樣
1. 假設你一顆按鈕是要用來取像的,您會取為grab
2. 假設你有兩顆按鈕都是用來取像的,您可以取grab1button和grab2button,但是要是一隻是用來照腳的,一隻是用來照臉的,那你可以取grabfootbutton和grabfacebutton,看起來很白癡,但起碼你看得出他是取腳影像的按鈕和取臉影像的按鈕
3. 當你有一個Group的元件是用來完成一個功能,那兩個不同Group的要給他們一個關鍵字區隔,像是一堆元件是用來管理資料庫相關的,一堆元件是用來儲存選項的,那管理資料庫的您可以取為databaseXXXbutton、databaseXXXPanel,相對地做選項用的您可取為optionXXXbutton、optionXXXtest,這樣都小寫其實看起來有意點吃力,因此您可以加個”_”來格出單字(option_XXX_button),或者是單字頭加個大寫(OptionXXXButton),總之命名就是要讓您自己可以看得出他是跟哪個功能有關的或是用途是幹嘛的
4. 當你有一個功能,假設是用來控制IO訊號(這要知道電子機械的人才懂,總之您可以想成就是一堆按鈕要用來把電腦旁邊的燈點亮或關掉),那像是他可能會有不同的class都存放跟這個有關的,Ex:
Class Option裡面有存IO對應的PIN腳位置和PIN是否啟用的變數,您可取為OptionIOXXXPin和OptionIOXXXPinEnabled,假設兩個IO一個是連線,一個是處理中
OptionIOConnectPin和OptionIOConnectPinEnabledOptionIODealPin和OptionIODealPinEnabled
Class Form1裡面有三種元件(Panel,Label,Picture),三個元件組成一個按鈕,
其中Picture是用來按的(有人說Picture只能來放圖和影像嗎),也就是Panel底下放著Label(標示IO名稱)和Picture(按鈕),假設您要輸出兩個IO一個是連線,一個是處理中,告訴別的機台(像是別的電腦或是PLC(這要寫電控才知道),總之就是把訊號送給別人)
IOConnectPanel、IOConnectLabel、IOConnectButtonIODealtPanel、IODealLabel、IODealButton
有沒有看到相關用途的命名其實很像,像連線中相關的東西命名都有個IOConnect,這樣有幾個好處
1. 假設您要把連線中改為啟動,您只要搜尋全部文件全部查IOConnect,他會找到相關的所有東西,這樣你只要把找到的地方IOConnect改成IOEnabled,就全部改完了,省的你要去記很多元件參數的命名方式,最後改的累死了
2.
你在打Code時可以用複製貼上的,例如你要存這兩個變數寫入檔案
Fprintf(“IOConnectPin = %d”, OptionIOConnectPin);
Fprintf(“IOConnectEnabled = %d”, OptionIOConnectPinEnabled);
那要是你要存處理中的變數,只需複製貼上把不一樣的地方改掉
Fprintf(“IODealPin
= %d”, OptionIODealPin); Fprintf(“IODealEnabled = %d”, OptionIODealPinEnabled);
通常這裡看不出來好處,但是您想想當您有20X個IO接點,5個不同變數要存,其實您按照這種一致性的命名方式,會比你一種一種打和亂取名稱寫Code快很多
.h都放定義,.cpp都放實作
這是比較良好的習慣,因為定義和實作混在一起,有時候會打結,實際打結是什麼,我並無法舉出例子,但是有時候code寫多了會出現錯誤,例如什麼函式重複定義,
當然您可以利用
#ifndef FILE1_H
#define FILE1_H
#endif
利用這個來保證.h只會被引用一次(這是舊式寫法)
他的意思是如果沒有FILE1_H定義,我就定義FILE1_H,而當下次您又重複引用這個頭檔,FILE1_H這時就有定義了,他就不會進去看#ifndef FILE1_H
到#endif內的Code
新的您可以使用
#pragma once
利用這個來確保引用的頭檔都只會被使用一次(但是通常學校沒有教這個,尤其越後段越沒教,總之如果您去後段學校聽課,您會發現都在教很古老的東西(就教授那個年代的東西,學完就沒再更新了))
又或者是有教,但是一般不會像我這樣附例子給人研究,就#pragma once
,它的定義是,您下課自己研究看看(我指比較老一輩的教授,教書10多年都講一樣的課程)雖然有新式的寫法,但是,其實我還是習慣順便也加入舊式寫法(比較安心0.0),其實應該是加一個就好了
如果您將實作和定義分開,您的.h就不會很亂,並且很龐大(因為你要實作程式(實作通常會有1兩千行,.h可能才50行而已,您混在一起就不好查您函式定義了)),
也就是說.h負責函式定義和註解,.cpp實作內容,然後當您.cpp太多行時,其實您可以做分類拆成兩個,這樣可以減少一個cpp的行數,像是您視窗的那個class Form1,您可能會下很多指令來處理介面元件,例如1+1=2,秀在一個Label上,當處理的東西很多,您的Form1.h就會發生我那個問題,到時候會很亂
所以請盡量只寫定義,其他建一個cpp放進去
當您Cpp也爆滿時,您可拆成數個cpp存放您實作的Code,例如做畫面Layout的放一個,控制畫面顏色的放一個,初始化設定的放一個,主要是看您的需要進行拆解,拆太多其實也不好,變成您檔案數太多了,你找函式也是很累
盡量將函式物件化(模組化),讓一個函式的Code不要太長,或者太多層
例如一個函式有500行,您可能就像我之前C++物件導向的基本知識(簡易函式化)那篇那樣物件化,而當您寫Code有四五層迴圈,也是盡量讓它看起來少一點(有時候寫演算法4~5迴圈是常態,避免不了),避免增加程式閱讀的困難
將您這個案子取一個英文名子,給他一個namespace放全域變數,或定義
例如您在公司接一個案子,通常會有個專案名稱,假設我的專案叫做Evytec,
那麼我會把我一些重要定義宣告放在namespace evytec下,並給他一個頭檔,當有用到這些定義或是全域變數,我在include該頭檔
好處就是您不用再去找Code看您要的定義在哪裡,整個案子重要的東西,去您的那個namespace的頭檔找就對了,要是有定義,例如您定義一個重要元件的大小,您把它定義化(就是弄一個定義或變數放到namespace裡),那要是你要改變該物件的大小,您就改定義就好了,
當然您也可以將一些設定的程式碼放在函式裡,並定義成全域變數,但是有個壞處,函式裡不能放定義,只能放變數(因為生命週期的問題)
養成好習慣做適當的註解
當然公司做案子都很趕,有時候您註解很浪費時間,而且通常公司做研發,通常核心不會一開始寫就是完整的演算法,一定會一改再改,您為了一個錯誤的演算法註解很完整,到時候改了您是不是又要在註解一次,您不會累嗎…
當然就算您這次沒註解,通常有個最適合做比較整體性的註解的時間,就是您成案了,也就是演算法初步可以滿足客戶基本需求,那您這時候可以找個時間去註解一下,避免您忘記您在寫什麼,這樣工作起來會比較有效率
理由就簡單啦,我目前公司接三個中大型案子,每年寫程式碼改1~2萬行(要是我花時間在那改註解,您確定我不會變成改程式5000行,改註解5000行嗎(重複改))
公司主管大部分經理不是寫Code專家(特別是小公司),會出一些鳥主義,叫您做無意義的工作,因為他以為仿效大公司治理,卻不知道這種動作,您說高手就算了,可以做,但剛畢業或是功力不佳的人做這種事,您註解了也沒人看得懂,案子趕又註解不好
最後變成寫Code寫不出來,註解也沒人看得懂,專案一拖再拖,小公司主管就用責任制將責任怪到您身上,卻不知導致這種負面循環的是他死腦筋造成(因為他不會寫一首好Code,當然沒有寫好Code的經驗,既然沒有寫好Code的經驗,他管你寫Code的任何東西,您確定可以幫助您完成嗎(前提要您有認真上班寫Code才可以有這種想法))
但是畢竟是主管0.0,還是要聽他的先(通常就敷衍一下),畢竟這個世界是結果論,所以你要先寫好Code,把案子完成,再來噹你主管頭殼壞掉,不然說真的您叫得再大聲,您Code就會生出來嗎,要知道自己是在幹什麼,用啥賺錢
盡量將您的函式打包,放在自己的namespace下或class下
因為會有命名問題,寫視窗程式您要曉得這支IDE有很多已經定義好的東西(例如int),要是您在程式不小心寫到相同的東西,例如您的class Vector有預設的.h檔已經定義了,您再定義一次會重複定義,放在您的namespace下或者class下,可以做一定的區隔,況且假設您跟我一樣接不少案子,其實一個領域有些東西是相似的,您可以把您打包好的東西,拿到別的案子用,達到所謂的reuse,可以節省很多您的開發時間,加快您完成您手中案子的速度
最重要的就是之前提過
C++很活,這語言寫法彈性很大,不要被您學校及舊的知識及經驗騙了
任何容器都可以互相包來包去(像是函式裡面可以寫struct),總之只要您的寫法,Compiler和Link會過,他就是對的,不要侷限在舊有框架,您會玩不出把戲
當然您要看過人家玩把戲,您才會知道原來可以這樣玩,所以還是必須去一些比較有技術的公司看看,薪水就看您覺得學東西重要還是高薪重要(但通常薪水付的比較高的大公司不會教您東西,關鍵技術守得很緊(像是台積電,他分工就很清楚,不會讓您亂摸))
累死了,工作前我還不知道我這麼會嘴砲XD
我的東西通常在您開始真的寫Code(起碼要一段長時間)後再看會比較有效過,一般沒特別寫過Code的看這個是浪費時間@3@
沒有留言:
張貼留言