中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
學(xué)習(xí)MISRAC之五:準(zhǔn)確的程序流控制——(轉(zhuǎn))

程序的執(zhí)行流程是由條件判斷、跳轉(zhuǎn)和循環(huán)構(gòu)成的,沒有任何一個(gè)程序會(huì)缺少程序流的控制。那么像if 、for 、while 、switch 等這些程序員無比熟悉的語句也存在隱患嗎? 事實(shí)上,C 語言是很靈活的,這種靈活性給程序員編寫代碼帶來了很多便利,但同時(shí)也帶來了很多容易導(dǎo)致混淆的表達(dá)。這些表達(dá)完全符合C 語言標(biāo)準(zhǔn),但有時(shí)程序員也難以發(fā)現(xiàn)自己犯了錯(cuò)誤,最終的結(jié)果是使程序進(jìn)入錯(cuò)誤的執(zhí)行流程。即使程序員沒有犯錯(cuò)誤,但有些容易混淆的表達(dá)也會(huì)給其他人讀懂程序帶來困擾,使程序的維護(hù)變得困難。除此以外,有少量控制流程的方式還會(huì)產(chǎn)生不確定的運(yùn)行結(jié)果,而這些結(jié)果也不容易被發(fā)覺。

如何使程序的流程控制清晰、準(zhǔn)確,不產(chǎn)生混淆的表達(dá)呢? MISRA C 給出了很多的相關(guān)規(guī)定,使程序流的控制變得規(guī)范,避免產(chǎn)生各種混淆和不確定性,從而最大程度上減少程序流控制中的失誤, 并使程序的維護(hù)更加容易。

下面從幾個(gè)例子出發(fā),講述這些混淆是如何產(chǎn)生的,最后給出MISRA C 關(guān)于程序流控制的相關(guān)規(guī)則,幫助讀者規(guī)范編程的習(xí)慣。

1 容易混淆的表達(dá)方式先來看這樣兩段代碼:

uint8_t x ,y ;

if ( x = = y) {

foo ( ) ;

}

uint8_t x ,y ;

if (x = y) {

foo ( ) ;

}

在C 標(biāo)準(zhǔn)中,條件語句需要的是布爾值,條件語句表達(dá)式的布爾值實(shí)際上是按照整型處理的,所以這兩段代碼在語法和邏輯上都沒有任何問題。第一段代碼判斷x 是否等于y ,如果相等,調(diào)用foo () 函數(shù);第二段代碼首先將y的值賦給x ,然后判斷x 是否為0 ,如果不為0 ,調(diào)用foo ()函數(shù)。這兩段代碼只相差一個(gè)等號(hào),卻使判斷條件大不相同,程序的執(zhí)行流程會(huì)出現(xiàn)很大差別。

相信讀者在寫程序的時(shí)候都碰到過將“= = ”這個(gè)判斷語句誤寫成賦值語句“= ”的情況。那么面對這兩個(gè)語句時(shí),如何能快速準(zhǔn)確地判斷這是正確的還是程序員的失誤呢? 當(dāng)程序比較簡單的時(shí)候,很容易判斷,但當(dāng)程序流程比較復(fù)雜的時(shí)候,可能花費(fèi)大量時(shí)間還難以給出確定的答案,而這些地方極有可能是有錯(cuò)誤的。

這樣的混淆,事實(shí)上是可以輕松避免的,MISRA C提出了如下強(qiáng)制性的規(guī)則。

規(guī)則13. 1 :賦值表達(dá)式不能用在需要布爾值的地方。

按照MISRA C 的標(biāo)準(zhǔn),第二段代碼應(yīng)該寫成:

uint8_t x ,y ;

x = y ;

if (x ! = 0) {

foo ( ) ;

}

這樣,當(dāng)看到需要布爾值的地方出現(xiàn)了賦值表達(dá)式,

就可以立即判斷這是一個(gè)錯(cuò)誤。在這條規(guī)則下,如下的表達(dá)也是不允許的:

if ( (x = y) ! = 0 ) ) {

foo ( ) ;

}

與這條規(guī)則類似,MISRA C 還提出了如下推薦的規(guī)則,來避免整型變量和布爾型的混淆。

規(guī)則13. 2 (推薦) :判斷一個(gè)值是否為0 應(yīng)該是顯式的,除非該操作數(shù)是一個(gè)布爾值。

這條規(guī)則禁止了如下的表達(dá):

uint8_t x ;

if ( x )

{ ?}

再來看一個(gè)例子:

uint8_t x ;

uint8_t a ,b ;

?

switch ( x ) {

case 1 :

a = b ;

case 2 :

a + = 2 ;

break ;

case 3 :

?

}

同樣,這段代碼在語法和邏輯上也沒有任何問題,編譯器也不會(huì)給出任何錯(cuò)誤或者警告。在程序執(zhí)行中,當(dāng)x等于1 的時(shí)候,將b 的值賦給a ,然后將a 加2 ,退出;當(dāng)x等于2 的時(shí)候,直接將a 的值加2 ,接著退出。但這兒很可能是一段錯(cuò)誤的代碼,程序員的本意有可能是x 等于1時(shí),將b 的值賦給a ,當(dāng)x 等于2 時(shí),直接將a 的值加2 。

為了避免這樣的混淆,MISRA C 提出了如下強(qiáng)制性的規(guī)則。

規(guī)則15. 2 :所有非空的switch 子句都應(yīng)該以break 語句結(jié)束。

按照這條規(guī)則,上面的程序應(yīng)該寫成:

switch ( x ) {

case 1 :

a = b ;

break ;

case 2 :

a + = 2 ;

break ;

case 3 :

?

}

或者:

switch ( x ) {

case 1 :

a = b ;

a + = 2 ;

break ;

case 2 :

a + = 2 ;

break ;

case 3 :

?

}

MISRA C 中還有一些防止程序流控制中出現(xiàn)混淆的規(guī)則。

規(guī)則13. 5 :for 語句中的3 個(gè)表達(dá)式只能和循環(huán)控制相關(guān)。第一個(gè)表達(dá)式只能為循環(huán)變量賦初值,第二個(gè)表達(dá)式只能進(jìn)行循環(huán)條件的判斷,第三個(gè)表達(dá)式只能進(jìn)行循環(huán)

變量增(減) 值。

規(guī)則13. 6 :for 循環(huán)中,循環(huán)變量只能在for 語句的第三個(gè)表達(dá)式中修改,不允許在循環(huán)體中修改。

規(guī)則13. 7 :布爾表達(dá)式的值必須是可以改變的。

例如,如下代碼是不允許的:

uint8_t x ;

?

if ( x >= 0 )

?

錯(cuò)誤在于該條件判斷的結(jié)果始終為真。

規(guī)則14. 1 :不能存在無法執(zhí)行到的代碼。

規(guī)則14. 2 : 非空語句必須要么產(chǎn)生副作用( side-effect) (副作用是指表達(dá)式執(zhí)行后對程序運(yùn)行環(huán)境造成的影響。賦值語句、自增操作等都是典型的具有副作用的操作。) ;或者使程序流程改變。

例如,下面的代碼是不允許的:

?

x > = 3 ;

?

錯(cuò)誤在于x 和3 比較的結(jié)果被丟棄了。

規(guī)則14. 3 :一行中如果有空語句,那么該行只能有這條空語句,不能有別的語句,并且在這條空語句前不能有注釋,注釋必須在其后,用空格隔開。

例如,如下的代碼都是不允許的:

while (port & 0x80 = = 0) {

; foo ( ) ; ①

/ * wait for pin * / ; ②

;/ * wait for pin * / ③

}

其中

①的錯(cuò)誤是除了空語句還有一條語句; 

②的錯(cuò)誤是在空語句前有注釋; 

③的錯(cuò)誤是空語句與注釋沒用空格隔開。

規(guī)則14. 8 : switch 、while 、do. . . while 和for 語句的主體必須是復(fù)合語句(即用大括號(hào)包含) ,即使該主體只包含一條語句。

例如,如下代碼是符合MISRA C 標(biāo)準(zhǔn)的:

for ( i = 0 ;i < N_EL EMEN TS ; + + i )

{

buffer [ i ] = 0 ;

}

規(guī)則14. 9 :if 結(jié)構(gòu)后面必須是一個(gè)復(fù)合語句(即用大括號(hào)包含) ,else 后面必須是一個(gè)復(fù)合語句(即用大括號(hào)包含) 或者另一個(gè)if 語句。

規(guī)則15. 1 : switch 語句的主體必須是復(fù)合語句(即用大括號(hào)包含) 。

規(guī)則15. 2 :所有非空的switch 子句都應(yīng)該用break 語句結(jié)束。

規(guī)則15. 3 : switch 的最后一個(gè)子句必須是default 子句,如果default 中沒有包含任何語句,那么應(yīng)該有注釋來說明為什么沒有進(jìn)行任何操作。

規(guī)則15. 4 : switch 表達(dá)式不能是一個(gè)有效的布爾值。

例如,下面的代碼是不允許的:

switch ( x = = 0 )

{ ?}

規(guī)則15. 5 : switch 語句必須至少包含一個(gè)case 子句。

2 導(dǎo)致混亂的表達(dá)方式

在C 語言中,有一些表達(dá)方式可以使程序的代碼量減少,但卻會(huì)使程序的結(jié)構(gòu)化程度降低,流程控制變得混亂,可讀性大大降低??聪旅嬉欢未a:

if ( a > 0x02 )

{

loop1 : b + = 1 ;

if ( c > 0xA0 ) {

goto loop3 ;

}

loop2 : a = 2 3 b ;

c = a + b ;

if ( c < 0x40) {

goto loop1 ;

}el se {

goto loop2 ;

}

}

?

loop3 : ?

這段代碼讀起來很困難。實(shí)際編程時(shí),程序員實(shí)現(xiàn)這段功能的代碼自然不會(huì)這樣寫,但是當(dāng)程序流程復(fù)雜的時(shí)候,各種看起來能使編程工作變得輕松的表達(dá),例如goto 、continue 等語句,卻會(huì)使程序流程變得混亂,可讀性降低,而隱藏其中的問題,很可能就無法發(fā)現(xiàn)了。

針對這種情況, MISRA C 給出了下面幾條強(qiáng)制規(guī)則。

規(guī)則14. 4 :不允許使用goto 語句。

規(guī)則14. 5 :不允許使用continue 語句。

規(guī)則14. 6 :循環(huán)體中最多只能出現(xiàn)一個(gè)break 語句用于結(jié)束循環(huán)。

規(guī)則14. 7 :函數(shù)只能有一個(gè)出口,這個(gè)出口必須在函數(shù)末尾。

規(guī)則14. 10 : if . . . else if 結(jié)構(gòu)必須由一個(gè)else 子句結(jié)束。

當(dāng)if 語句后面有一個(gè)或者多個(gè)else if 語句時(shí),最后的一個(gè)else if 必須有一個(gè)與之對應(yīng)的else 語句。如果只有一個(gè)if 語句時(shí),else 不是必須的。

3  不確定的執(zhí)行結(jié)果除了導(dǎo)致混淆和混亂的表達(dá)外,還有一些對浮點(diǎn)數(shù)的操作會(huì)導(dǎo)致不確定的結(jié)果。來看如下一段代碼:

float32_t x ,y ;

? / 3 一些運(yùn)算3 /

if ( x = = y )

{ ?}

if 的條件無法肯定什么情況為真。這是因?yàn)楦↑c(diǎn)數(shù)在計(jì)算機(jī)中無法用二進(jìn)制精確表示,其運(yùn)算總會(huì)存在舍入和切斷誤差,很多人看起來相等的結(jié)果,但計(jì)算機(jī)給出的兩個(gè)浮點(diǎn)數(shù)并不相等,所以上面代碼中if 的主體語句什么情況執(zhí)行是不確定的。MISRA C 給出了兩條相關(guān)的規(guī)定來解決這一問題。

規(guī)則13. 3 :不允許對浮點(diǎn)數(shù)進(jìn)行相等或者不相等的比較,即使是非直接的比較也是不允許的。

例如,如下非直接的比較也是不允許的:

float32_t x ,y ;

?

if ( x < = y )

{ ?}

規(guī)則13. 4 :for 循環(huán)的控制表達(dá)式不應(yīng)包含浮點(diǎn)數(shù)類型。

4  小 結(jié)好的代碼,要安全可靠、有很好的可讀性和可維護(hù)性。在C 語言中,一些表達(dá)方式,可能會(huì)稍微減少程序員編程的工作量,但卻會(huì)使程序的流程變得難以判斷,其中的錯(cuò)誤可能就無法發(fā)現(xiàn)。

按照MISRA C 的標(biāo)準(zhǔn)來寫代碼,就可以避免程序流程產(chǎn)生混淆和混亂,排除其中的不確定因素,使程序真正按照程序員設(shè)想的工作,并使代碼更清晰易懂,真正實(shí)現(xiàn)安全可靠,并具有良好的可讀性和可維護(hù)性。

參考文獻(xiàn)

1  MISRA C:2004 ,Guidelines for the use of the C language in critical systems. The Motor Indust ry Software Reliability As2sociation ,2004

2  Harbison III. Samuel P , Steele J r. Guy L. C 語言參考手冊,

邱仲潘,等譯,第5 版. 北京:機(jī)械工業(yè)出版社,2003

3  Les Hatton. The MISRA C Compliance Suite The next step , Oakwood Computing. http :/ / www. misra c2. com/

4  ISO/ IEC 9899 :1999. International Organization of Standardi2zation , 1999

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
MISRA C:讓嵌入式系統(tǒng)更加安全可靠的一些關(guān)鍵規(guī)則
快速上手系列-C語言之基礎(chǔ)篇(一)
Java語句:Java空語句、復(fù)合語句和表達(dá)式語句
MISRA C編程規(guī)范標(biāo)準(zhǔn)
讀書日志:代碼大全之第十七章
MySQL JOIN查詢
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服