為了提高源程序的質(zhì)量和可維護(hù)性,從而最終提高軟件產(chǎn)品生產(chǎn)力,特編寫此規(guī)范。本標(biāo)準(zhǔn)規(guī)定了程序設(shè)計(jì)人員進(jìn)行程序設(shè)計(jì)時(shí)必須遵循的規(guī)范。本規(guī)范主要針對(duì)單片機(jī)編程語(yǔ)言和08編譯器而言,包括排版、注釋、命名、變量使用、代碼可測(cè)性、程序效率、質(zhì)量保證等內(nèi)容。 n c% ^5 `6 c1 f# p+ u& ^
1.基本規(guī)則
' S) }; V3 W( U- A! C$ r+ g. f格式清晰、注釋簡(jiǎn)明扼要、命名規(guī)范易懂、函數(shù)模塊化、程序易讀易維護(hù)、功能準(zhǔn)確實(shí)現(xiàn)、代碼空間效率和時(shí)間效率高、適度的可擴(kuò)展性、單片機(jī)編程規(guī)范-標(biāo)識(shí)符命名
/ v: u) w. @. M) |* u, Z4 R2.標(biāo)識(shí)符命名 2.1 命名基本原則 , c& _% y+ F/ }4 s1 t/ O4 a
(1)命名清晰明了,有明確含義,使用完整單詞或約定俗成的縮寫。通常,較短的單詞可通過去掉元音字母形成縮寫;較長(zhǎng)的單詞可取單詞的頭幾個(gè)字母形成縮寫。即"見名知意"。(2)命名風(fēng)格要自始至終保持一致。 + E" F; |3 [! l5 H+ I. |3 [% G5 p
(3)命名中若使用特殊約定或縮寫,要有注釋說明。9 v) [/ L+ Z9 B, M' [& a/ k& M
(4)同一軟件產(chǎn)品內(nèi)模塊之間接口部分的標(biāo)識(shí)符名稱之前加上模塊標(biāo)識(shí)。
' ~' L M0 ^ B6 K8 `2 D1 \( q2.2 宏和常量命名
& N& t5 I+ D$ B$ O& Y l宏和常量用全部大寫字母來命名,詞與詞之間用下劃線分隔。對(duì)程序中用到的數(shù)字均應(yīng)用有意義的枚舉或宏來代替。; S; ]6 O% c* |( r
2.3 變量命名 ) e7 M* G/ r6 A4 V+ v$ J( {8 g+ r+ @& p
變量名用小寫字母命名,每個(gè)詞的第一個(gè)字母大寫。類型前綴(u8\s8 etc.)全局變量另加前綴g_。9 H- M' ]" X6 t/ J! S) w4 ^5 U! H
局部變量應(yīng)簡(jiǎn)明扼要。局部循環(huán)體控制變量?jī)?yōu)先使用i、j、k等;局部長(zhǎng)度變量?jī)?yōu)先使用len、num等;臨時(shí)中間變量?jī)?yōu)先使用temp、tmp等。9 M5 [7 y' E* F: |- ^
2.4 函數(shù)命名 8 g4 H' ~4 q# N; P9 e2 ]4 G
函數(shù)名用小寫字母命名,每個(gè)詞的第一個(gè)字母大寫,并將模塊標(biāo)識(shí)加在最前面。, X+ K8 R% ^! W. L3 x& P6 \# b( Y
2.5 文件命名 : N% _2 R! R9 D
一個(gè)文件包含一類功能或一個(gè)模塊的所有函數(shù),文件名稱應(yīng)清楚表明其功能或性質(zhì)。
/ p. g' `8 Y9 y4 u$ I; g每個(gè).c文件應(yīng)該有一個(gè)同名的.h文件作為頭文件。 - k2 S8 H m* J( Y
3.注釋 3.1 注釋基本原則
/ s, \$ [( i9 _% {4 \8 k. e有助于對(duì)程序的閱讀理解,說明程序在"做什么",解釋代碼的目的、功能和采用的方法。
$ ~3 V# {" X3 O& Y& W/ Y- H5 d一般情況源程序有效注釋量在30%左右。
" Z! g6 e, W5 W) G注釋語(yǔ)言必須準(zhǔn)確、易懂、簡(jiǎn)潔。
4 |$ f) S( ~$ j2 W- J' ~1 n. r邊寫代碼邊注釋,修改代碼同時(shí)修改相應(yīng)的注釋,不再有用的注釋要?jiǎng)h除。2 }7 {$ l$ O: B, V5 [
匯編和C中都用"//",取消";" 不使用段注釋" /* */ "(調(diào)試時(shí)可用) , w- b5 Y1 n/ v
3.2 文件注釋
1 E, ~4 I% K2 L) q: g& g" L文件注釋必須說明文件名、函數(shù)功能、創(chuàng)建人、創(chuàng)建日期、版本信息等相關(guān)信息。' A5 y2 x5 E+ q C0 {3 }# M2 E
修改文件代碼時(shí),應(yīng)在文件注釋中記錄修改日期、修改人員,并簡(jiǎn)要說明此次修改的目的。所有修改記錄必須保持完整。 [# [$ ?3 V5 t) b- }
文件注釋放在文件頂端,用"/*……*/"格式包含。
% p3 Z) Q4 j9 b; b注釋文本每行縮進(jìn)4個(gè)空格;每個(gè)注釋文本分項(xiàng)名稱應(yīng)對(duì)齊。
) o; `: Z t( C8 j/***********************************************************
, `5 q, J+ E7 b2 m. b5 B6 u文件名稱:
7 w1 E/ N. V8 b+ O" s作 者:
3 |5 m- K# ?, B @版 本:
1 a% _9 n6 ~6 e說 明:; q" V7 U6 x- u8 [: z) q2 s6 r# ^+ m8 [
修改記錄:; j$ [; u( p) ^3 I6 \0 H
***********************************************************/; b! K3 V$ O) h/ X/ @
3.3 函數(shù)注釋
! b3 V% z& W' K3.3.1 函數(shù)頭部注釋
D& a! j3 v+ r8 P: a. I- H0 m函數(shù)頭部注釋應(yīng)包括函數(shù)名稱、函數(shù)功能、入口參數(shù)、出口參數(shù)等內(nèi)容。如有必要還可增加作者、創(chuàng)建日期、修改記錄(備注)等相關(guān)項(xiàng)目。
1 K" v; J8 Y2 u. D1 J2 Q函數(shù)頭部注釋放在每個(gè)函數(shù)的頂端,用"/*……*/"的格式包含。其中函數(shù)名稱應(yīng)簡(jiǎn)寫為Name(),不加入、出口參數(shù)等信息。
* s9 O/ L% r h/ w( L4 |+ ^/***********************************************************( x; U* Y. p0 Z, B
函數(shù)名稱:: J3 p5 q5 v4 s" \ h
函數(shù)功能:6 d% O5 y" o% a6 S A: A
入口參數(shù):/ y5 W+ R; ~) d$ ~
出口參數(shù):
$ N5 O. s, S/ D4 q1 |- V c$ r) [備 注:
4 S( G% ~3 s3 i. B2 b, w0 n***********************************************************/
& x- q7 X' S' a3.3.2 代碼注釋
8 C& X C2 r' e' V* f; y4 w代碼注釋應(yīng)與被注釋的代碼緊鄰,放在其上方或右方,不可放在下面。如放于上方則需與其上面的代碼用空行隔開。一般少量注釋應(yīng)該添加在被注釋語(yǔ)句的行尾,一個(gè)函數(shù)內(nèi)的多個(gè)注釋左對(duì)齊;較多注釋則應(yīng)加在上方且注釋行與被注釋的語(yǔ)句左對(duì)齊信盈達(dá)嵌入式企鵝要妖氣嗚嗚吧久零就要。1 G2 h( t; _1 L; A9 N3 o9 o8 } g m9 J
函數(shù)代碼注釋用"//…//"的格式。
; Q- k9 o5 Q- F l通常,分支語(yǔ)句(條件分支、循環(huán)語(yǔ)句等)必須編寫注釋。其程序塊結(jié)束行"}"的右方應(yīng)加表明該程序塊結(jié)束的標(biāo)記"end of ……", 尤其在多重嵌套時(shí)。. D% Z( S% U+ Y3 l5 o! [8 l* i
3.4 變量、常量、宏的注釋
5 N! L- L: G* e- _同一類型的標(biāo)識(shí)符應(yīng)集中定義,并在定義之前一行對(duì)其共性加以統(tǒng)一注釋。對(duì)單個(gè)標(biāo)識(shí)符的注釋加在定義語(yǔ)句的行尾。, M- G f- I1 O$ @
全局變量一定要有詳細(xì)的注釋,包括其功能、取值范圍、哪些函數(shù)或過程存取它以及存取時(shí)的注意事項(xiàng)等。
; b% ~0 O; D, b! j9 [: |* j' }注釋用"//…//"的格式。
; X. C1 W. l& [. \+ `4.函數(shù) 4.1 函數(shù)設(shè)計(jì)原則 $ H; o: a6 T2 c T. d
函數(shù)的基本要求: . T/ G9 W- s7 p e
1)封裝性
1 X( n. C/ ^ @. m4 W1) 正確性:程序要實(shí)現(xiàn)設(shè)計(jì)要求的功能。: ^5 T7 m$ s$ a' S0 f& [: ^
2) 穩(wěn)定性和安全性:程序運(yùn)行穩(wěn)定、可靠、安全。/ f- ~8 j! E# T% W C
3) 可測(cè)試性:程序便于測(cè)試和評(píng)價(jià)。8 G0 \4 P8 I/ E# d; u
4) 規(guī)范/可讀性:程序書寫風(fēng)格、命名規(guī)則等符合規(guī)范。5 h7 ?, P& Y8 Q" ^) _
5) 擴(kuò)展性:代碼為下一次升級(jí)擴(kuò)展留有空間和接口。. i- D* i& n3 d* H0 f
6) 全局效率:軟件系統(tǒng)的整體效率高。
) w9 w/ D( q8 P# B7) 局部效率:某個(gè)模塊/子模塊/函數(shù)的本身效率高。
/ D7 H# I7 o* z1 e, a' x& H編制函數(shù)的基本原則:, Y4 T2 l( ~# r
1) 單個(gè)函數(shù)的規(guī)模盡量限制在200行以內(nèi)(不包括注釋和空行)。一個(gè)函數(shù)只完成一個(gè)功能。
: x5 S5 o9 [& g9 { I- ]8 [2) 函數(shù)局部變量的數(shù)目一般不超過5~10個(gè)。+ d( O7 [% P9 c
3) 函數(shù)內(nèi)部局部變量定義區(qū)和功能實(shí)現(xiàn)區(qū)(包含變量初始化)之間空一行。
1 C) t J. ~& x8 B4) 函數(shù)名應(yīng)準(zhǔn)確描述函數(shù)的功能。通常使用動(dòng)賓詞組為執(zhí)行某操作的函數(shù)命名。- ]3 t. \5 f0 f: V& q" h
5) 函數(shù)的返回值要清楚明了,尤其是出錯(cuò)返回值的意義要準(zhǔn)確無誤。
5 a* Y) ?: t7 t1 s+ |2 U- @5 h( @2 o6) 不要把與函數(shù)返回值類型不同的變量,以編譯系統(tǒng)默認(rèn)的轉(zhuǎn)換方式或強(qiáng)制的轉(zhuǎn)換方式作為返回值返回。# X: w6 E( e3 U- I
7) 減少函數(shù)本身或函數(shù)間的遞歸調(diào)用。
8 B1 U0 ^1 j4 M! u1 D0 G8) 盡量不要將函數(shù)的參數(shù)作為工作變量。
0 d' e2 L( _# u+ o1 G4.2 函數(shù)定義
9 W' z% Q6 ]2 M( {1) 函數(shù)若沒有入口參數(shù)或者出口參數(shù),應(yīng)用void明確申明。
! o, _% n+ n, S& ~9 C2) 函數(shù)名稱與出口參數(shù)類型定義間應(yīng)該空一格且只空一格。
/ }) {* d9 d. a# J/ }' \3 ]( Q8 Y3) 函數(shù)名稱與括號(hào)()之間無空格。- g& _" S/ [* Z3 n
4) 函數(shù)形參必須給出明確的類型定義。* M9 u: r6 r, t% ~5 G/ U
5) 多個(gè)形參的函數(shù),后一個(gè)形參與前一個(gè)形參的逗號(hào)分割符之間添加一個(gè)空格。8 d+ b; I: m, ?1 u
6) 函數(shù)體的前后花括號(hào)"{}" 各獨(dú)占一行。2 X- _6 _# [ z; [
4.3 局部變量定義
6 I5 x7 Y H/ \/ f1) 同一行內(nèi)不要定義過多變量。' L( J9 p1 b7 X+ z+ p
2) 同一類的變量在同一行內(nèi)定義,或者在相鄰行定義。
`6 W+ u4 R" q& S8 K9 B# l4 c8 ?3) 先定義data型變量,再定義idtata型變量,再定義xdata型變量.(?)
! Q) Z& b) f4 x, r. q" N4) 數(shù)組、指針等復(fù)雜類型的定義放在定義區(qū)的最后。
' O! I" a; W3 P' G q5) 變量定義區(qū)不做較復(fù)雜的變量賦值。
+ ?# p5 ]6 B0 X7 M& b' Y4.4 功能實(shí)現(xiàn)區(qū)規(guī)范 0 [7 ~; U' U3 E0 h$ S: M
1) 一行只寫一條語(yǔ)句。
. l) P$ x" T2 Y% T- r' D2) 注意運(yùn)算符的優(yōu)先級(jí),并用括號(hào)明確表達(dá)式的操作順序,避免使用默認(rèn)優(yōu)先級(jí)信盈達(dá)嵌入式企鵝要妖氣嗚嗚吧久零就要。7 {6 ^3 W+ Q* d2 F+ a: m) o
3) 各程序段之間使用一個(gè)空行分隔,加以必要的注釋。程序段指能完一個(gè)較具體的功能的一行或多行代碼。程序段內(nèi)的各行代碼之間相互依賴性較強(qiáng)。(1、2、3方式) c4 \( @8 t& ~$ ~/ f2 s
4) 不要使用難懂的技巧性很高的語(yǔ)句。
% P) _6 T2 r. ^# v+ f& k5) 源程序中關(guān)系較為緊密的代碼應(yīng)盡可能相鄰。
8 k2 _/ }2 G) }* i/ Y N6 C6) 完成簡(jiǎn)單功能、關(guān)系非常密切的一條或幾條語(yǔ)句可編寫為函數(shù)或定義為宏。 $ _$ Y1 n" W, k. S5 z
5. 單片機(jī)編程規(guī)范-排版
% F% f- c9 y& V3 H% c# H7 S! X5.1 縮進(jìn) ' V/ O& m/ ^1 O8 z( G7 _
代碼的每一級(jí)均往右縮進(jìn)4個(gè)空格的位置。不使用Tab鍵 / A$ c4 b5 s2 ~
5.2 分行
$ I) }+ Y% p" S) f4 o8 @5 A每行語(yǔ)句(?????超過80個(gè)字符)要分成多行書寫;長(zhǎng)表達(dá)式要在低優(yōu)先級(jí)操作符處劃分新行,操作符放在新行之首,劃分出的新行要進(jìn)適當(dāng)?shù)目s進(jìn),使排版整齊,語(yǔ)句可讀。避免把注釋插入分行中。
0 [+ x. Y0 l2 B' g0 v; |% |7 w; t5.3 空行 ! e; n! J3 d# }
1) 文件注釋區(qū)、頭文件引用區(qū)、函數(shù)間應(yīng)該有且只有一行空行。6 v6 `- ~9 P: r5 h/ ?$ j8 ~
2) 相鄰函數(shù)之間應(yīng)該有且只有一行空行。
% H, S3 @- g q+ T3 Y3) 函數(shù)體內(nèi)相對(duì)獨(dú)立的程序塊之間可以用一行空行或注釋來分隔。; Z$ J; o. M# g: M
4) 函數(shù)注釋和對(duì)應(yīng)的函數(shù)體之間不應(yīng)該有空行。
2 i2 z" |9 V3 W$ d6 v5) 文件末尾有且只有一行空行。 G8 t" ?& b% U$ G2 Y+ T2 }
5.4 空格
$ J/ d5 D$ U, T1 }, Z1) 函數(shù)語(yǔ)句尾部或者注釋之后不能有空格。4 q$ o( M( O' n1 J' c
2) 括號(hào)內(nèi)側(cè)(即左括號(hào)后面和右括號(hào)前面)不加空格,多重括號(hào)間不加空格。0 m i2 t' D: Y, y" _
3) 函數(shù)形參之間應(yīng)該有且只有一個(gè)空格(形參逗號(hào)后面加空格)。 j4 e" W- D- a) s" L
4) 同一行中定義的多個(gè)變量間應(yīng)該有且只有一個(gè)空格(變量逗號(hào)后面加空格)。) v5 l% J& V( |! q; e
5) 表達(dá)式中,若有多個(gè)操作符連寫的情況,應(yīng)使用空格對(duì)它們分隔:
( \) s, D, k$ H6) 在兩個(gè)以上的關(guān)鍵字、變量、常量進(jìn)行對(duì)等操作時(shí),它們之間的操作符前后均加一個(gè)空格;在兩個(gè)以上的關(guān)鍵字、變量、常量進(jìn)行非對(duì)等操作時(shí),其前后均不應(yīng)加空格;! r4 { _& L) ^( f$ S$ L0 F) C
7) 逗號(hào)只在后面加空格;
7 M2 ]' Q4 e) m% a7 T8) 雙目操作符,如比較操作符, 賦值操作符"="、"+=",算術(shù)操作符"+"、"%",邏輯操作符"&&"、"&",位操作符"<<"、"^"等,前后均加一個(gè)空格;5 |) S; Y5 B3 I: l$ x( K6 e+ a: ]
9) 單目操作符,如"!"、"~"、"++"、"-"、"&"(地址運(yùn)算符)等,前后不加空格;
( n* |' d: X9 _( A) K! K10) "->"、"."前后不加空格;( [4 J( A0 T7 R1 r p' Q- C
11) if、for、while、switch等關(guān)鍵字與后面的括號(hào)間加一個(gè)空格;8 f5 S0 `4 L4 N* {* S
5.5 花括號(hào) 8 N5 _ B! g" K& i
1) if、else if、else、for、while語(yǔ)句無論其執(zhí)行體是一條語(yǔ)句還是多條語(yǔ)句都必須加花括號(hào),且左右花括號(hào)各獨(dú)占一行。
9 {* P* q# ~$ g2) do{}while()結(jié)構(gòu)中,"do"和"{"均各占一行,"}"和"while();"共同占用一行。
+ q) O/ ]% V' N; [if ( ) do- f, X. N, T( j
{ {
7 k; N$ {( E7 x9 V9 \- s$ q3 B} }while( );
/ i! ?2 Y' y! O4 L* Felse5 N" x8 K) ?+ `9 M% Q
{$ d! B8 S& v0 Q9 B
}
+ H2 N) n! A+ S* S# c+ a嵌套越少越好,{}不準(zhǔn)超過3層
" K6 j+ }1 ~0 L2 O( o& F8 M' r' ? h5.6 switch語(yǔ)句 # V+ S. C' b& v, h" U0 {/ q" c
1) 每個(gè)case和其判據(jù)條件獨(dú)占一行。: d# y ~8 m( N6 g; c
2) 每個(gè)case程序塊需用break結(jié)束。特殊情況下需要從一個(gè)case塊順序執(zhí)行到下一個(gè)case塊的時(shí)候除外,但需要花括號(hào)在交界處明確注釋如此操作的原因,以防止出錯(cuò)。
/ X2 E. @9 S" N* t$ d' x+ t, D2 V3) case程序塊之間空一行,且只空一行。' Y, A7 ~9 S3 [ \: C
4) 每個(gè)case程序塊的執(zhí)行語(yǔ)句保持4個(gè)空格的縮進(jìn)。
- I! P/ r# x3 @0 o5) 一般情況下都應(yīng)該包含default分支。
% B1 B: t1 q' o* u: bSwitch ( )) }, E7 W( l. f& y' t) ?* ]5 v, z; G
{
* }, Y+ C m \1 [5 U4 ?" s: l# n; Ecase x:" N5 B1 C1 m* K, O: |. ^- E
break;
) j) w! u+ _+ d# W% A% A; i+ scase x:2 l, D2 a) G8 Y; M* V
break;; f" @4 ]* s; Q% _; G4 l4 K
default:
1 q; M( T3 R# e O6 l! H' `# A9 O% gbreak;
8 @! v% Y: ~6 I$ d}
0 g# w# K3 q; \ b6.程序結(jié)構(gòu) 6.1 基本要求
9 o/ M; d9 Q7 q" K! C) |: A1) 有main()函數(shù)的.c文件應(yīng)將main()放在最前面,并明確用void聲明參數(shù)和返回值。
1 U7 A5 u! m& d& x+ y- D: `+ i" q" F2) 對(duì)由多個(gè).c文件組成的模塊程序或完整監(jiān)控程序,建立公共引用頭文件,將需要引用的庫(kù)頭文件、標(biāo)準(zhǔn)寄存器定義頭文件、自定義的頭文件、全局變量等均包含在內(nèi),供每個(gè)文件引用。通常,標(biāo)準(zhǔn)函數(shù)庫(kù)頭文件采用尖角號(hào)< >標(biāo)志文件名,自定義頭文件采用雙撇號(hào)″″標(biāo)志文件名。0 [: U$ Y. T b' F8 o2 ?
3) 每個(gè).c文件有一個(gè)對(duì)應(yīng)的.h文件,.c文件的注釋之后首先定義一個(gè)唯一的文件標(biāo)志宏,并在對(duì)應(yīng)的.h文件中解析該標(biāo)志。' ~" N; P. o/ ?9 `* Z! R
在.c文件中:8 l7 H5 Z* ]& P ~5 F
#define FILE_FLAG
# O( F9 x* F' {2 M7 J' _9 |在.h文件中:&
- c8 }7 }7 j$ A+ [2 Z/ o6.程序結(jié)構(gòu) 6.1 基本要求 . l A9 _! L+ X+ D$ h/ t
1) 有main()函數(shù)的.c文件應(yīng)將main()放在最前面,并明確用void聲明參數(shù)和返回值。
1 `) }! \3 |8 a4 w/ @+ p2) 對(duì)由多個(gè).c文件組成的模塊程序或完整監(jiān)控程序,建立公共引用頭文件,將需要引用的庫(kù)頭文件、標(biāo)準(zhǔn)寄存器定義頭文件、自定義的頭文件、全局變量等均包含在內(nèi),供每個(gè)文件引用。通常,標(biāo)準(zhǔn)函數(shù)庫(kù)頭文件采用尖角號(hào)< >標(biāo)志文件名,自定義頭文件采用雙撇號(hào)″″標(biāo)志文件名。+ [$ B4 f/ e: F9 A7 c
3) 每個(gè).c文件有一個(gè)對(duì)應(yīng)的.h文件,.c文件的注釋之后首先定義一個(gè)唯一的文件標(biāo)志宏,并在對(duì)應(yīng)的.h文件中解析該標(biāo)志。
6 }: V7 N1 P5 o# A# M在.c文件中:
3 k R6 l6 y: r( G#define FILE_FLAG
. v! P; {4 x- _" Z \5 V6 q% O在.h文件中:
2 v- ^" ^1 n |1 o; {#ifdef FILE_FLAG0 [# G1 N% s8 t. x0 D4 E( F
#define XXX% ~4 ^6 C5 N) I0 F# S3 U
#else
$ O# O' {/ N: Z& x! G#define XXX extern
% a8 Z4 Q6 Z* \#endif
9 p0 a) P, T3 A4) 對(duì)于確定只被某個(gè).c文件調(diào)用的定義可以單獨(dú)列在一個(gè)頭文件中、單獨(dú)調(diào)用。# `5 w3 t4 n3 @ M0 ^
! @! Y7 \6 }; ?5 { ]9 E. [
|