日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于单片机代码的风格

發布時間:2023/12/14 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于单片机代码的风格 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

程序不僅要被計算機讀,還要給程序員讀。一個風格清爽而嚴謹的程序更容易被讀懂,更容易被修改和排錯。良好的編程風格和正確的習慣還有助于保持思維清晰,寫出正確無誤的代碼。特別是一個開發團隊共同工作時,保持一致的編程風格尤其重要。目前單片機開發人員對編程風格問題重視度還不夠。事實上,每個初學者在項目初期都會因為不良編程習慣浪費大量時間,因此若能在開始寫程序時就重視編程風格問題,對順利渡過提高階段有很大幫助。篇幅所限,本節僅淺述編程風格幾個最基本原則。

一、變量命名規則

變量名盡量使用具有說明性的名稱,避免使用 a,b,c,x,y,z 等無意義字符。使用范圍大的變量,如全局變量,更應該有一個說明性的名稱。變量名盡量使用名詞,長度控制在1~4個單詞最佳。若名稱包含多個單詞,每個單詞首字母大寫以便區分單詞,例如:

int InputVoltage; //輸入電壓 int Temperature; //溫度

當單詞間必須出現空格才好理解的時候,可以用下劃線’_’替代空格:

int Degree_C; //攝氏度 int Degree_F; //華氏度

當單詞較長的時候,可以適當簡寫:

int NumOfInputChr; //輸入字符數 int InputChrCnt; //輸入字符數 int Deg_F; //華氏度

一旦約定某方式簡寫,以后必須保持風格統一。
若多個模塊都可能出現某個變量,可以按“模塊名_變量名”的方式命名:

char ADC_Status; // ADC 的狀態 char BT_IntervalFlag; // BasicTimer 定時到達標志 int UART_RxCharCnt; // 串口收到的字符總數


對于約定俗成的變量,如用變量 i、j 做為循環變量,p、q 作為指針,s、t 表示字符串等,不要改動。這里采用更長的變量名反而不符合習慣。

二、函數命名規則

和變量一樣,函數名稱也應具有說明性。函數名應使用動詞或動作性名字,后面可以跟名詞說明操作對象。按照“模塊名_功能名”的方式命名:

unsigned int ADC16_Sample(); //16 位 ADC 采樣 char LCD_Init(); //LCD 初始化 char RTC_GetVal(); //獲取實時鐘的數據 void PWM_SetPeriod(); //設置 PWM 周期 void PWM_SetDuty(); //設置 PWM 占空比 void Flash_WriteChar(); //向 Flash 寫入一字節數據 char UART_GetChar(); //從串口讀取一字節數據 char Key_GetKey(); //從鍵盤讀取一次按鍵 char TouchPad_GetKey(); //從觸摸板讀取一次按鍵


每個單詞首字母大寫,便于閱讀,專有名詞或縮略詞(ADC/LCD 等)全部大寫。遇到太長的單詞也可以在不影響閱讀的情況下適當簡寫,例如用Tx替代單詞Transmit,Rx替代單詞Receive,Num替代單詞Number,Cnt替換Count,數字2(Two)替代單詞To等。和變量一樣,一旦約定某種簡寫方式,以后必須保持風格統一。對于所有模塊都通用的函數,如求均值函數,可以不寫模塊名。對于返回值是布爾類型值的函數(真或假),名稱應清楚反映返回值情況,例如編寫某函數檢查串口發送緩沖區是否填滿:

char UART_CheckTxBuff(); //不恰當的函數名 char UART_IsTxBuffFull(); //意義明確的函數名


第一個函數字面意思是“檢查發送緩沖區”,若返回真(1)表示什么意思不明確。
第二個函數字面意思是“發送緩沖區滿了么?”,若返回真(1)有明確的意思:滿了。

三、表達式

表達式應該盡量自然、簡潔、無歧義。寫代碼的時候,要杜絕各類“技巧”。我們的目標是要寫最清晰的代碼,而不是最巧妙的代碼。下面2個表達式所表達的條件是等價的,第一個邏輯拐了個彎,難以理解,寫成第二種表達方式就清晰許多。

if(!(RxCharNum<20)||(!(RxCharNum>=16)) //晦澀的表達式 if((RxCharNum>=20)||(RxCharNum<16)) //清晰的表達式


再看下面的表達式想要干什么?
SubKey=SubKey>>(Bits-(Bits/8)*8); //難懂的表達式
最內層表達式把Bits除以8再乘以8,實際上相當于把最低三位清零。再從 Bits 原值減去這個結果,實際上相當于取Bits的最低3位。最后用這三位確定SubKey的移位次數。實際上與下面簡潔的表達式等價:
SubKey=SubKey >> (Bits & 0x07); //清晰的表達式 SubKey >>= (Bits & 0x07); //清晰的表達式 SubKey >>= (Bits%8); //清晰的表達式
一個好的表達式應該能夠用英語朗讀出來。可以作為檢驗表達式好壞的依據。例如:
if(UART_IsTxBuffFull()) UART_ClearTxBuff(); else UART_PutChar(0x55);
上面的表達式可以被朗讀出來: “如果串口發送緩沖區滿了,就清空發送緩沖區,否則從串口發送字符 0x55”,可讀性很好。
表達式不僅要清晰,還要消除歧義。若初學者對i++ 和++i順序比較含糊,完全可以將表達式拆開避免歧義。若對運算符優先級問題沒有把握,可以用括號消除可能出現的歧義。

四、風格一致性

對于書寫格式,向來爭議很大,例如括號配對就有 2 種流行的寫法:
for(i=0;i<100;i++){for(j=0;j<200;j++){ //括號配對風格 1...} } while(a==b){if(c==d){ //括號配對風格 1...}else{...} }


另一種寫法是
for(i=0;i<100;i++){ //括號配對風格 2for(j=0;j<200;j++){...}} while(a==b) {if(c==d){ //括號配對風格 2...}else{...} }
除了書寫風格,命名方法也有很多種標準,且經常可以看到哪種格式更好的討論。事實上,最好的格式、最好的命名方法是和慣用風格保持一致。如果加入一個開發團隊,團隊目前所使用的風格就是最好的格式;如果改寫別人寫的程序,保持原程序的風格就是最好的風格。總之,程序的一致性比本人的習慣更重要。如果初學者還沒有形成自己的風格,那么可以參考官方提供的范例程序,或者與平臺供應商的代碼保持風格一致。

五、注釋

注釋是幫助程序讀者的一種手段,但是如果注釋只是代碼的重復,將會變得毫無意義。若注釋與代碼矛盾,反倒會幫倒忙。最好的注釋是簡潔明了的點明程序的突出特征,或者闡明思路,或提供宏觀的功能解釋,或者指出特殊之處,以幫助別人理解程序。比較同一段代碼的兩種注釋方法:
for(i=6;i>DOT;i--) //從第 6 位(最高位)到小數點之間依次遞減 {if (DispBuff[i]==0) DispBuff[i]=’ ’; //如果該位數值是 0,則替換成空格else break; //如果不是,則跳出循環 }
另一種注釋方法
for(i=6;i>DOT;i--) {if (DispBuff[i]==0) DispBuff[i]=’ ’; //消隱顯示數據小數點前的無效 0else break; }
第1種注釋每行都有注釋,但讀者仍然不明白這段程序功能或目的是什么。因為每個注釋無非是代碼的解釋和重復。第2種注釋雖然只有1行,但簡明扼要的說明了這個for循環的功能,幫助讀者理解程序。寫注釋的時候要從讀程序的思路來考慮而不要以設計者的角度思考。對于每個函數,特別是底層函數,都要注釋。在函數前面注釋該函數的名稱、參數、參數值域、返回值、設計思路、功能、注意事項等。如果參與團隊開發,還應寫若干典型應用范例,供他人參考。商業化的代碼中,注釋比程序長的情況很常見。在代碼維護、調試與排錯時,若修改代碼,要養成立即修改注釋的習慣,否則很容易出現代碼與注釋不一致的情況,很可能造成難以排查的錯誤,嚴重影響工作效率。

六、宏定義

數值沒有任何能表達自身含義的可讀性,因此對于程序中出現的數值,他們應該有自己的名字。一般可以用宏定義來實現,并且用宏定義處理數據之間的關系。在寄存器操作章節中,我們已經看到頭文件中對寄存器地址、標志位等都作了宏定義,用宏對寄存器賦值后,程序立刻有了可讀性。類似的,我們可以用宏定義來對常數數值賦予可讀性。

#define TXBUFF_SIZE (128) /*發送緩沖大小*/ #define LCM_ROW (64) /*點陣液晶行數*/ #define LCM_CLUMN (128) /*點陣液晶列數*/ #define LCM_BUF_SIZE (LCD_CLUMN*LCD_ROW/8) /*點陣液晶緩沖區大小*/


將常數值用宏定義之后寫出來的代碼可讀性增強了:
unsigned char TxBuff[TXBUFF_SIZE]; //定義發送緩沖區char IsTxBuffFull() {if(NumOfTxChars>=TXBUFF_SIZE) return(1); //緩沖區是否滿?else return(0); }
在上例中,一旦需要改變緩沖區大小,只需要修改宏定義即可。宏定義屬于字符型替代,因此在使用宏定義的時候要注意防止產生歧義。例如數據全部加括號,以免和程序前后文構成意料之外的運算優先級。宏定義后的注釋使用 /**/而不要用// ,以免某些版本的編譯器在代碼中將宏定義連同注釋全部替換造成錯誤。
使用宏定義還要防止定點計算溢出,例如:
#define VOLT_RATE (1000) /*比例系數*/ ... int Voltage; int InputValue; ... Voltage=InputValue*VOLT_RATE; //可能溢出
若將宏定義做如下修改即可避免溢出問題:
#define VOLT_RATE ((long)1000) /*比例系數,強整成 long*/




摘自《MSP430系列單片機系統設計與實踐》第一章第六節

總結

以上是生活随笔為你收集整理的关于单片机代码的风格的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。