博客專欄

EEPW首頁(yè) > 博客 > 編程規(guī)范哪家強(qiáng) Misra C姊妹篇再上場(chǎng)

編程規(guī)范哪家強(qiáng) Misra C姊妹篇再上場(chǎng)

發(fā)布人:三德子 時(shí)間:2022-05-23 來(lái)源:工程師 發(fā)布文章

據(jù)說(shuō),在中國(guó)的演藝界,有兩個(gè)圈最講究規(guī)矩了。 

一個(gè)是小品圈,以東北王為代表,一個(gè)頭磕到地上,便入了趙家門,得守趙氏家法。 

還有一個(gè)便是相聲界,長(zhǎng)幼尊卑更是秩序森嚴(yán),跟師父鬧掰便是叛出師門,在相聲界基本上便沒(méi)有了立足之地。 

還有便是軍隊(duì),更是紀(jì)律嚴(yán)明,講究個(gè)戰(zhàn)前且莫議論紛紛,開戰(zhàn)便要萬(wàn)眾一心。因?yàn)?,主帥有令,將士效命,才能攻無(wú)不克,戰(zhàn)無(wú)不勝。您不信?君不見(jiàn),楊主簿啃著雞肋上斷頭臺(tái)否? 

楊修.jpg

編程這種“小事”,同樣也得守規(guī)矩!

1、編程規(guī)范的重要性

之前,灑家寫過(guò)一篇《編程規(guī)范哪家強(qiáng) 我把Misra C講一講》,大致講了Misra C誕生的背景及其規(guī)則背后的原因。今天,灑家不惜筆墨,苦口婆心,跟大家談一談編程規(guī)范的重要性。 

孔老夫子總結(jié)自己一生時(shí)曾曰:吾十有五而志于學(xué),三十而立,四十而不惑,五十而知天命,六十而耳順,七十而從心所欲,不逾矩。 

吾十有五而志于學(xué).jpg

西方人秉承Follow your heart,搞得毒品泛濫,小姐滿大街??桌戏蜃訁s能做到“從心所欲,不逾矩”,為什么? 

因?yàn)?,?dāng)持戒成為一種習(xí)慣,不逾矩便成了從心所欲的自然。持守戒律、遵守規(guī)矩非但不會(huì)處處束縛你,反而讓你在道德準(zhǔn)則、社會(huì)秩序允許的范圍內(nèi)得到最大程度的自由。那些淺薄的西方人,是把這個(gè)邏輯搞反了呀! 

風(fēng)箏是自由的,是因?yàn)橛懈€,讓它既能翱翔于九天,又能隨時(shí)隨刻被拉牽?;疖囀亲杂傻模且?yàn)橛幸浑p鐵軌,讓它既能風(fēng)馳電掣越千山,又能平平穩(wěn)穩(wěn)進(jìn)車站。代碼是自由的,是因?yàn)橛幸?guī)范,讓它既能把您的所思所想付諸實(shí)踐,又能避免翻車,給你瞎搗亂。 

對(duì)于寫代碼來(lái)說(shuō),編程規(guī)范不會(huì)限制自由,它只會(huì)限制滋生混亂 

一個(gè)不遵循規(guī)范的代碼不僅僅虱子多了真犯愁,bug多了直撓頭,還會(huì)在閱讀、修改、維護(hù)上會(huì)遇到理解上的障礙。 

對(duì)于剛上手不久的菜鳥級(jí)碼農(nóng)來(lái)說(shuō),遵循規(guī)范意味著嚴(yán)格的自律、小心翼翼和偏執(zhí),但這能減少bug和隱患。而且,一旦養(yǎng)成了習(xí)慣,習(xí)慣就變成了自然,這時(shí)候,不符合規(guī)則的代碼一入你的法眼,你就不由自主地要把它改掉,讓這些不規(guī)矩的代碼快滾蛋。 

對(duì)一個(gè)組織而言,遵守統(tǒng)一的編程規(guī)范意味著書同文、車同軌,就像月老的紅絲線,把大家伙的心兒緊相連,從而大幅提高協(xié)作效率,真正做到團(tuán)隊(duì)作戰(zhàn)。

2、面向可靠性/安全的設(shè)計(jì)規(guī)范

這世上有一個(gè)神奇的二八定律,比方說(shuō)20%的人掌握著世界上80%的財(cái)富,20%的人干著80%的活。。。 

干過(guò)大批量量產(chǎn)電子產(chǎn)品的攻城獅們還發(fā)現(xiàn),20%的時(shí)間能干成80%的活,接下來(lái)要用80%的時(shí)間,把剩下20%的細(xì)節(jié)好好打磨。 

之所以如此,是因?yàn)檫@些產(chǎn)品在上市前需要經(jīng)過(guò)研發(fā)團(tuán)隊(duì)非常嚴(yán)苛的反復(fù)測(cè)試。為什么要反復(fù)測(cè)試?不要問(wèn),問(wèn)就是不懂!難不成,出了問(wèn)題,你能牛得像特斯拉那樣非但拒絕認(rèn)錯(cuò),還要教育教育用戶? 

那么,“嚴(yán)苛”在哪里?“反復(fù)測(cè)試”些什么呢?除了正常邏輯、常規(guī)條件,還需要反復(fù)測(cè)試Corner case(邊界條件/邊角案例)! 

佛說(shuō),萬(wàn)事萬(wàn)物,因緣和合而生,因緣別離而滅。大部分條件下,因緣和合,產(chǎn)品穩(wěn)定運(yùn)行,但一旦超過(guò)了某個(gè)臨界點(diǎn),滿足了邊界條件,如果處理失當(dāng),就可能因緣別離,功能失常了。 

何謂邊界條件?其定義并不統(tǒng)一,從實(shí)際應(yīng)用來(lái)講,一般是指很少發(fā)生的情景、參數(shù)異常、噪聲或者極端情況。開發(fā)產(chǎn)品需要充分考慮邊界條件,或施加約束,針對(duì)處理,或圍住撈凈,避免漏網(wǎng),它會(huì)直接關(guān)乎到產(chǎn)品的可靠性和功能安全。 

但是,產(chǎn)品的可靠性是設(shè)計(jì)出來(lái)的,而非靠測(cè)試測(cè)出來(lái)。在最初的設(shè)計(jì)階段就納入功能安全的理念,才能強(qiáng)本固基,扎下可靠性的底盤。 

對(duì)于內(nèi)嵌C代碼的電子產(chǎn)品而言,可靠性/功能安全和代碼的靈活性卻往往是一體兩面,王不見(jiàn)王,二龍不相見(jiàn)。C語(yǔ)言的靈活性,可以助力高手鬼斧神工,天外飛仙,也能讓菜鳥處處挖坑,埋下風(fēng)險(xiǎn)。 

凡事皆是破壞容易建設(shè)難,在靈活的語(yǔ)言特性下,要把程序寫糟很容易,寫好很難。如果沒(méi)有一個(gè)嚴(yán)格、安全的設(shè)計(jì)規(guī)范來(lái)把關(guān),很容易把代碼寫爛 

Misra C,正是為了對(duì)治C語(yǔ)言的靈活性、提高代碼的可靠性橫空出世的尚方寶劍。 

Misra C規(guī)則,大多來(lái)自一線工程師/專家多年的編程實(shí)踐,提煉于多年軟件設(shè)計(jì)的教訓(xùn)經(jīng)驗(yàn)。一時(shí)理解不了,也是正常表現(xiàn),您只需多多編程實(shí)戰(zhàn),切不可自以為是,兩眼朝天。 

畢竟,法律條文都會(huì)看,但只有羅老師的粉絲過(guò)千萬(wàn)!

羅翔.jpg

3、MISRA-C 規(guī)則分類及舉例

務(wù)虛務(wù)實(shí),相得益彰,上點(diǎn)干貨,才見(jiàn)真章。下面跟大家分享,Misra C針對(duì)C語(yǔ)言的籬笆下的一些樁。

 3.1 被誤解的語(yǔ)言特性

3.1.1 char只用作字符

畢達(dá)哥拉斯學(xué)派有一句名言:萬(wàn)物皆數(shù)。生于俄羅斯的我國(guó)大詩(shī)仙李白對(duì)此深有體會(huì),因?yàn)樗哉Z(yǔ):白發(fā)三千丈,緣愁似個(gè)長(zhǎng)?也曾大聲驚呼:飛流直下三千尺,疑是銀河落九天。 

詩(shī)仙何以不識(shí)數(shù)?因?yàn)?,在他的慧眼里,?shù)不是數(shù),是帶著詩(shī)情畫意的字符。在計(jì)算機(jī)的世界里,也有這樣一個(gè)獨(dú)特的數(shù)據(jù)類型char,你也不要把它當(dāng)成數(shù),而要當(dāng)成字符。 

首先,這意味著它的取值區(qū)間是[-128,127],其次,char型應(yīng)該只用做字符”,不要當(dāng)成“數(shù)字”來(lái)用??纯聪旅孢@個(gè)例子: 

char i;

i = 131;

if(i > 130){

    Fun();

}

會(huì)如你所愿地執(zhí)行Fun()?當(dāng)然,不會(huì)! 

所以,Misra C規(guī)則5.1規(guī)定,“單純的char類型只能用于存儲(chǔ)和使用字符值。  

3.1.2自動(dòng)變量不會(huì)自動(dòng)初始化

先上個(gè)例子:

uint8_t Fun(void)

{

    uint8_t i;

    ...

    if(0 == i){

        Fun2();

    }

} 

同樣,不會(huì)執(zhí)行Fun2()。 

很多人會(huì)自以為是地想,科技在發(fā)展,時(shí)代在進(jìn)步,現(xiàn)在的開發(fā)環(huán)境這么友好,它肯定會(huì)把變量i自動(dòng)賦值為0的吧? 

答案是No! C語(yǔ)言里,只有全局變量和靜態(tài)局部變量會(huì)默認(rèn)賦值為0,非靜態(tài)的局部變量隨機(jī)賦值,所以,Misra C規(guī)則9.1規(guī)定:所有自動(dòng)變量在使用前都應(yīng)該被賦值! 

3.2 增強(qiáng)程序的清晰

3.2.1 定義清晰的數(shù)據(jù)類型

應(yīng)該使用指示了大小和符號(hào)的typedef 以代替基本數(shù)據(jù)類型,灑家在16位單片機(jī)上定義的常用類型如下:

typedef signed char    sint8_t;

typedef unsigned char  uint8_t;

typedef signed int      sint16_t;

typedef unsigned int   uint16_t;  

typedef float          float32_t;

typedef unsigned long  uint32_t;  

3.2.2 不要使用逗號(hào)運(yùn)算符

比如下面這段代碼占了5行:

if(TRUE == Val){

    motor->pointer = 0;

    motor->pointer_old = 0;

    motor->cmd_dir = CLKWISE;

}

有的偏執(zhí)狂為了精簡(jiǎn)行數(shù),改成下面這樣的兩行:

if(TRUE == Val)

motor->pointer = 0, motor->pointer_old = 0, motor->cmd_dir = CLKWISE;

 

好多人get不到這種方式的缺點(diǎn)。想想一個(gè)場(chǎng)景,如果這是你從別人手中接手的代碼,看著怪不怪?是不是懷疑哪個(gè)逗號(hào)搞錯(cuò)了,應(yīng)該改成分號(hào)來(lái)著?

程序員惡趣味.jpg 

這背后,是律己從寬、料敵從嚴(yán)的人性?。?/span> 

3.3杜絕奇技淫巧-笨拙則魯棒

對(duì)工程師來(lái)說(shuō),天才的設(shè)計(jì)是真正的浪漫。在自己得意的作品中留下一些小心思,是碼農(nóng)們對(duì)庸常生活的一種反抗。 

于是,各種花哨的小動(dòng)作就出現(xiàn)在了本該嚴(yán)謹(jǐn)?shù)木幋a實(shí)踐中。舉個(gè)例子:

uint8_t *** ptr;

指向xx的指針的指針的指針,多燒腦,多“美妙”。 

可是,君子藏器于身,以鈍示人,以鋒策己。搞得這么花里胡哨,真以為過(guò)了一段時(shí)間自己能記牢?

 

3.4 不要依賴編譯器

不要過(guò)分依賴C表達(dá)式中的運(yùn)算符優(yōu)先規(guī)則

比如下面這個(gè)程序:

uint8_t  ial,iah;

uint16_t ia; 

ia = ial + iah << 8; 

初衷很簡(jiǎn)單,將兩個(gè)八位數(shù)據(jù)連接成一個(gè)16位數(shù)據(jù)。上面的錯(cuò)誤在哪里?‘+’的優(yōu)先級(jí)大于‘<<’,所以應(yīng)該改成下面這種形式: 

ia = ial + (iah << 8); 

 

不知不覺(jué),文章就變得又臭又長(zhǎng)了。收工!

 

文:三少爺

 

 


*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。

超聲波液位計(jì)相關(guān)文章:超聲波液位計(jì)原理


液位計(jì)相關(guān)文章:磁翻板液位計(jì)原理





相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉