嵌入式C语言编程——.h文件与.c文件
.h文件與.c文件的關系
????參考高手的程序時,發現別人寫的嚴格的程序都帶有一個“KEY.H”,里面定義了.C文件里用到的自己寫的函數,如Keyhit()、Keyscan()等。.H文件就是頭文件,估計就是Head的意思吧,這是規范程序結構化設計的需要,既可以實現大型程序的模塊化,又可以實現根各模塊的連接調試。
.H文件介紹:
????在單片機嵌入式C程序設計中,項目一般按功能模塊化進行結構化設計。將一個項目劃分為多個功能,每個功能的相關程序放在一個C程序文檔中,稱之為一個模塊,對應的文件名即為模塊名。一個模塊通常由兩個文檔組成,一個為頭文件*.h,對模塊中的數據結構和函數原型進行描述;另一個則為C文件*.c ,對數據實例或對象定義,以及函數算法具體實現。
.H文件的作用
????作為項目設計,除了對項目總體功能進行詳細描述外,就是對每個模塊進行詳細定義,也就是給出所有模塊的頭文件。通常H頭文件要定義模塊中各函數的功能,以及輸入和輸出參數的要求。模塊的具體實現,由項目組成根據H文件進行設計、編程、調試完成。為了保密和安全,模塊實現后以可連接文件OBJ、或庫文件LIB的方式提供給項目其他成員使用。由于不用提供源程序文檔,一方面可以公開發行,保證開發人員的所有權;另一方面可以防止別人有意或無意修改產生非一致性,造成版本混亂。所以H頭文件是項目的詳細設計和團隊工作劃分的依據,也是對模塊進行測試的功能說明。要引用模塊內的數據或算法,只要用包含include指定模塊H頭文件即可。
.H文件的基本組成
/*如下為鍵盤驅動的頭文檔*/#ifndef _KEY_H_ //防重復引用,如果沒有定義過_KEY_H_,則編譯下句#define _KEY_H_ //此符號唯一, 表示只要引用過一次,即#i nclude,則定義符號_KEY_H_/ char keyhit( void ); //擊鍵否 unsigned char Keyscan( void ); //取鍵值 /#endif盡量使用宏定義#define
????開始看別人的程序時,發現程序開頭,在文件包含后面有很多#define語句,當時就想,搞這么多標示符替換來替換去的,麻不麻煩啊,完全沒有理解這種寫法的好處。原來,用一個標示符表示常數,有利于以后的修改和維護,修改時只要在程序開頭改一下,程序中所有用到的地方就全部修改,節省時間。
#define KEYNUM 65//按鍵數量,用于Keycode[KEYNUM] #define LINENUM 8//鍵盤行數 #define ROWNUM 8//鍵盤列數????注意的地方:
宏名一般用大寫
宏定義不是C語句,結尾不加分號
不要亂定義變量類型
????以前寫程序,當需要一個新的變量時,不管函數內還是函數外的,直接在程序開頭定義,雖然不是原則上的錯誤,但是很不可取的作法。下面說一下,C語言中變量類型的有關概念。從變量的作用范圍來分,分為局部變量和全局變量:
全局變量:是在函數外定義的變量,全局變量在程序全部執行過程中都占用資源,全局變量過多使程序的通用性變差,因為全局變量是模塊間耦合的原因之一。
局部變量:在函數內部定義的變量,只在函數內部有效。
????從變量的變量值存在的時間分為兩種:
靜態存儲變量:程序運行期間分配固定的存儲空間。
動態存儲變量:程序運行期間根據需要動態地分配存儲空間。
????具體又包括四種存儲方式:
auto
static
register
extern
????不加說明默認為auto型,即動態存儲,如果不賦初值,將是一個不確定的值。而將局部變量定義為static型的話,則它的值在函數內是不變的,且初值默認為0。編譯時分配為靜態存儲區,可以被本文件中的各個函數引用。如果是多個文件的話,如果在一個文件中引用另外文件中的變量,在此文件中要用extern說明。不過如果一個全局變量定義為static的話,就只能在此一個文件中使用。register定義寄存器變量,請求編譯器將這個變量保存在CPU的寄存器中,從而加快程序的運行。
特殊關鍵字const volatile的使用
const
??? const用于聲明一個只讀的變量。
const?unsigned?char?a=1;//定義a=1,編譯器不允許修改a的值????作用:保護不希望被修改的參數。
volatile
????一個定義為volatile的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設這個變量的值了。精確地說就是,優化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器里的備份。
static int i=0; int main(void) { ... while (1) { if (i) dosomething(); } } /* Interrupt service routine. */ void ISR_2(void) { i=1; }????程序的本意是希望ISR_2中斷產生時,在main當中調用dosomething函數,但是,由于編譯器判斷在main函數里面沒有修改過i,因此可能只執行一次對從i到某寄存器的讀操作,然后每次if判斷都只使用這個寄存器里面的“i副本”,導致dosomething永遠也不會被調用。如果將將變量加上volatile修飾,則編譯器保證對此變量的讀寫操作都不會被優化(肯定執行)。
????一般說來,volatile用在如下的幾個地方:
中斷服務程序中修改的供其它程序檢測的變量需要加volatile;
多任務環境下各任務間共享的標志應該加volatile;
存儲器映射的硬件寄存器通常也要加volatile說明,因為每次對它的讀寫都可能由不同意義。
聲明:
本文于網絡整理,版權歸原作者所有,如來源信息有誤或侵犯權益,請聯系我們刪除或授權事宜。
總結
以上是生活随笔為你收集整理的嵌入式C语言编程——.h文件与.c文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 消防备案取消了(消防备案取消)
- 下一篇: 电信手机版(电信安卓版)