我們會將其宣告(declaration)在一個.h檔(header file)裡面,然後就可以在需要的.c檔引用該.h檔
這樣一來可以避免在每個.c檔都做一次宣告的麻煩
此外當需要對宣告做修改時也僅需要修改.h檔即可
例如我們希望宣告一個structure來表示一個pixel中的RGB三色,並讓此宣告可以橫跨多個.c檔使用
我們可以新增一個color.h檔,並在裡面加入此structure即可
color.h
#ifndef _COLOR_H_
#define _COLOR_H_
typedef struct ColorPixel
{
int R;
int G;
int B;
} COLOR;
#endif // _COLOR_H_
為了避免重複引用(multiple inclusions)而出現redefinition的錯誤
通常我們會在.h檔加入macro (如上例color.h中藍色部分)
在程式編譯時,若發現_COLOR_H_已經被定義(define),則會忽略macro所包含的內容
如此就不會重複宣告COLOR這個structure了
而這個define的名稱習慣上會以檔案名稱前後加底線,並全部大寫來表示(dot也以底線取代)
例如color.h就會寫成_COLOR_H_
養成此習慣可以避免不同檔案不小心定義到相同的名稱,造成此機制失效
如此一來,我們就能在任意.c檔引入color.h來使用COLOR這個structure了
再來,使用.h檔的一個大原則就是只做宣告(declaration),不做定義(definition)
如果偷懶在.h檔做定義的話,當編譯時若產生多個.o檔(object file)的話
就會出現重複定義(multiple definition)的錯誤
color.h
#ifndef _COLOR_H_
#define _COLOR_H_
typedef struct ColorPixel
{
int R;
int G;
int B;
} COLOR;
COLOR sFirstPixel = {255, 255, 255};
#endif // _COLOR_H_
如上例,我們在color.h裡面直接定義了一個變數sFirstPixel
此時又因為不同的.c檔同時引用color.h
造成每個.c檔編譯出來的.o檔都包含此變數,因此在linking階段就會出現重複定義(multiple definition)的錯誤
那如果想要讓sFirstPixel這個變數可以跨檔案使用怎麼辦?
在其中一個.c檔定義後,其他.c檔使用extern來存取
如下範例
A.c
#include "color.h"
COLOR sFirstPixel = {255, 255, 255};
B.c
#include "color.h"如此一來就還是可以跨檔案共用同一個變數囉~
extern COLOR sFirstPixel;
最後再整理一下.h檔的使用好習慣
1. 每個.h檔加入各自的macro(#ifndef, #define, #endif)來防止重複引用,define命名時可使用檔名來避免取到相同名稱
2. 僅在.h檔做宣告(declaration)而不做定義(define)
3. 跨檔案使用的變數定義在.c檔,並搭配使用extern來共用
沒有留言:
張貼留言