淺談C工程中的.c與.h檔案

來源:互聯網
上載者:User

基於C語言的單片機、arm相關的工程開發時,C語言的模組化特點體現的非常明顯。試想一下:你的一個工程中需要用到AD採樣模組、液晶顯示模組、串口發送模組、DA控制模組等。你肯定不會選擇在一個.c檔案中進行,必須是分模組的,這樣才有利於團隊開發,提高效率。

那麼模組化設計遵循著怎樣的原則呢,應該怎麼寫.c,.h檔案呢。

1. .c和.h檔案的區別

通常意義上的說法,.c是源檔案,.h是標頭檔。通常為了創作者為了保護其代碼,而把.c檔案封裝起來,不公開,而將。.h檔案提供。此時.h相當於介面,供程式員調用。

但是實際上我們自己編寫.h,.c檔案時會發現.c與.h檔案裡面的內容其實並沒有什麼區別。在.c中寫的代碼同樣可以在.h檔案寫。

2.工程中使用.c,.h檔案

總的來說,.h檔案有兩種使用方法。

方法一:

正是由於1中藍色部分的描述的原因。我們會發現好多工程中某個模組只有.h檔案,而沒有.c檔案

 

以的DSP開發【瑞泰提供的常式為例】其工程中ICETEK-VC5509-EDU.h檔案中包含了對12864液晶屏的寄存器地址定義,相關操作函數定義。並沒有寫相關的.c檔案。然後在lcd.c檔案中調用ICETEK-VC5509-EDU.h。這樣的做法是可行的,為什麼可行,上面1中已經講得很清楚。

但是我們再來思考一個問題。如果這個工程中我又添加了一個ad.c。在ad.c中我們需要用到液晶顯示,那麼我們得調用ICETEK-VC5509-EDU.h 。如果我們這麼做了,工程編譯連結會通過嗎?

肯定不會,會報define duplicated //重複定義的錯誤,為什麼呢? include "ICETEK-VC5509-EDU.h"相當於把這句話替換成ICETEK-VC5509-EDU.h中的內容,而ICETEK-VC5509-EDU.h中對液晶的寄存器都進行了定義,初始化,函數都已經定義了。你在兩個檔案中引用ICETEK-VC5509-EDU.h,肯定會報重複定義的錯誤。

這種方法適用於單模組,或者某個模組不會被多個.c檔案調用

 

方法二:在.c檔案中進行變數,數組,函數的定義,在.h檔案中進行變數,數組,函數的聲明。

C語言支援的是一處定義,多處聲明【這裡所講的聲明指的是狹義上的聲明,引用聲明,即不會進行記憶體配置】

現在將上述的ICETEK-VC5509-EDU.h分成.c和.h檔案

首先在.h檔案中開頭寫上

#ifndef __ICETEK-VC5509-EDU_H 
#define __ICETEK-VC5509-EDU_H //防止重複定義,名字與.c相同
#endif

 

然後就要進行進一步的操作

(1)宏定義,宏定義是遇到此變數即替換

所以放在.h檔案中

如:

// McBSP0  ------------------------------------------------------
#define SPCR0 (*(unsigned int *)0x018c0008)
#define PCR0 (*(unsigned int *)0x018c0024)
#define SPCR01 (*(unsigned int *)0x01900008)
#define SPCR02 (*(unsigned int *)0x0)

 

(2)函數,函數的定義和聲明比較清晰

.h檔案進行聲明

void InitInterrupt(void);   // 初始化中斷
void InitCTR();      // 初始化ICETEK-CTR
void CloseCTR();     // 關閉ICETEK-CTR上各裝置

.c檔案進行定義

void CloseCTR()
{
    CTRGR=0;     
    CTRLR=0; CTRLR=0x40;
    CTRLR=0x0c0;
 LCDCMD(LCDCMDTURNOFF); 
 dbClearKey=CTRCLKEY;
 LBDS=0;
}

這樣就可以實現多個.c檔案加.h標頭檔,而不會導致重複定義的問題。

 

(3)數組等變數

變數的聲明和定義在單個檔案時好像都不怎麼區分的。

變數的聲明:指明變數名,變數類型。

變數的定義:指名變數名,變數類型,分配記憶體空間。

eg int  a; //定義

extern int a; //聲明

如果進行了賦值,則肯定是定義

extern int a=0; //定義

 

所以在.h檔案中:

extern unsigned char ledbuf[8],ledx[8];
extern unsigned char dbClearKey;
extern unsigned char ledkey[10][8];
extern unsigned int music[nMusicNumber][2];

//變數聲明

.c檔案:

unsigned int pwm[8]={ 0x86,0x87,0x83,0x8b,0x89,0x8d,0x8c,0x8e };
//變數必須要定義
unsigned char dbClearKey; //必須要定義
unsigned  char ledbuf[8];
unsigned char ledx[8];

 

在這地方還是有個疑問的,在.h檔案中如果不加extern 編譯也是可以通過的,那麼unsigned char ledbuf[8]也能表示聲明。【.h檔案是先被載入進.c檔案,所以.h中unsigned  char ledbuf[8]是最先執行的。為什麼表示的是聲明呢】

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.