歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C語言頭文件組織

C語言頭文件組織

日期:2017/3/1 9:38:28   编辑:Linux編程

一、全局變量單獨編寫(很值得借鑒)。
一般習慣將不同功能模塊放到一個頭文件和一個C文件中。

C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm

讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm

讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm

讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm

將C語言梳理一下,分布在以下10個章節中:

  1. Linux-C成長之路(一):Linux下C編程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
  2. Linux-C成長之路(二):基本數據類型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
  3. Linux-C成長之路(三):基本IO函數操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
  4. Linux-C成長之路(四):運算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
  5. Linux-C成長之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
  6. Linux-C成長之路(六):函數要義 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
  7. Linux-C成長之路(七):數組與指針 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
  8. Linux-C成長之路(八):存儲類,動態內存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
  9. Linux-C成長之路(九):復合數據類型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
  10. Linux-C成長之路(十):其他高級議題

例如是寫一些數學計算函數:

//mymath.h
#ifndef _mymath_H
#define _mymath_H
extern int Global_A; //聲明必要的全局變量
......
extern void fun(); //聲明必要的外部函數
.....
#endif

//mymath.h
#ifndef _mymath_H
#define _mymath_H
extern int Global_A; //聲明必要的全局變量
......
extern void fun(); //聲明必要的外部函數
.....
#endif

//mymath.c
#include "mymath.h "
#include <一些需要使用的C庫文件>

int Global_A; //定義必要的全局變量和函數
void fun();

int a,b,c; //定義一些內部使用的全局變量
void somefun();

//函數實現體
void fun()
{

}
void somefun()
{

}

//mymath.c
#include "mymath.h "
#include <一些需要使用的C庫文件>

int Global_A; //定義必要的全局變量和函數
void fun();

int a,b,c; //定義一些內部使用的全局變量
void somefun();

//函數實現體
void fun()
{

}
void somefun()
{

}哪個C文件需要使用只需包含頭文件mymath.h就可以了。

但是我認為上面的方法雖然好,但是上面定義全局變量的方式在比較大的工程中引起不便,一個模塊與其他模塊的數據傳遞最好通過專有的函數進行,而不要直接通過數據單元直接傳遞(這是VC++的思想),因此不建議在模塊的頭文件中聲明全局變量;全局變量最好統一定義在一個固定的文件中,所以可以采用下面的方法:

定義一個Globel_Var.C文件來放全局變量,然後在與之相對應的Globel_Var.H文件中來聲明全局變量
例如:
——————————————————————————————————

//Globel_Var.c
/*******定義本工程中所用到的全局變量*******/
int speed;
int torque;


//Globel_Var.c
/*******定義本工程中所用到的全局變量*******/
int speed;
int torque;


——————————————————————————————————

//Globel_Var.H
/*******聲明本工程中所用到的全局變量*******/
extern int speed;
extern int torque;

//Globel_Var.H
/*******聲明本工程中所用到的全局變量*******/
extern int speed;
extern int torque;

——————————————————————————————————
這樣哪個文件用到這兩個變量就可以在該文件的開頭處寫上文件包含命令;例如aa.C文件要用到speed,toque兩個變量,可以在aa.H文件中包含Globel_Var.H文件。
——————————————————————————————————

//aa.H文件
#include “Globel_Var.H”

extern void fun(); //聲明必要的接口函數

//aa.H文件
#include “Globel_Var.H”

extern void fun(); //聲明必要的接口函數

//aa.c文件
#include “aa.H”//每個程序文件中包含自己的同名頭件
int a,b,c; //定義一些本文件內部使用的局部變量
void somefun();

//函數實現體
void fun()
{
int d,e,f; //定義一些本函數內部使用的局部變量

}
void somefun()
{

}

//aa.c文件
#include “aa.H”//每個程序文件中包含自己的同名頭件
int a,b,c; //定義一些本文件內部使用的局部變量
void somefun();

//函數實現體
void fun()
{
int d,e,f; //定義一些本函數內部使用的局部變量

}
void somefun()
{

}

——————————————————————————————————
在bb.c文件中用到aa.c文件中的函數void fun()或變量的文件可以這樣寫

//bb.H文件
#include “aa.H”

extern int fun_1(void);//聲明本文件的接口函數

//bb.H文件
#include “aa.H”

extern int fun_1(void);//聲明本文件的接口函數

//bb.c文件
#include “bb.H”

int fun_1(void)
{

fun();//調用aa.C文件中的fun()函數

}

//bb.c文件
#include “bb.H”

int fun_1(void)
{

fun();//調用aa.C文件中的fun()函數

}

——————————————————————————————————
在主函數中可以這樣寫:主文件main沒有自己的頭文件

//main.c文件
#include<系統庫文件>
#include “Globle_Var.H”
#include “aa.H”
#include “bb.H”


char fun_2();//聲明主文件所定義的函數
int i,j; //定義一些本模塊內部使用的局部變量
char k;

void main()
{

fun();

i = fun_1();

k = fun_2();

}

char fun_2()
{

}

//main.c文件
#include<系統庫文件>
#include “Globle_Var.H”
#include “aa.H”
#include “bb.H”

char fun_2();//聲明主文件所定義的函數
int i,j; //定義一些本模塊內部使用的局部變量
char k;

void main()
{

fun();

i = fun_1();

k = fun_2();

}

char fun_2()
{

}

——————————————————————————————————
這樣即不會報錯又可以輕松使用全局變量。

二、如果在全局變量前加入static或者const(隱式為static類型的變量)
如下

// xxxx.h
...
const double PI = 3.1415926;
static void* NULL = 0;
...
//

// xxxx.h
...
const double PI = 3.1415926;
static void* NULL = 0;
...
//這個頭文件是可以包含在多個編譯單元的。

三、頭文件編寫參考以下基本的規則
理想的情況下,一個可執行的模塊提供一個公開的接口,即使用一個*.h文件暴露接口,但是,有時候,一個模塊需要提供不止一個接口,這時,就要為每個定義的接口提供一個公開的接口。在C語言的裡,每個C文件是一個模塊,頭文件為使用這個模塊的用戶提供接口,用戶只要包含相應的頭文件就可以使用在這個頭文件中暴露的接口。所有的頭文件都建議參考以下的規則:

1. 頭文件中不能有可執行代碼,也不能有數據的定義,只能有宏、類型(typedef,struct,union,menu),數據和函數的聲明。

例如以下的代碼可以包含在頭文件裡:


#define NAMESTRING “name”
typedef unsigned long word;
menu{ flag1,flag2};

typedef struct
{
int x;
int y;
}Piont;

extent Fun(void);
extent int a;

#define NAMESTRING “name”
typedef unsigned long word;
menu{ flag1,flag2};

typedef struct
{
int x;
int y;
}Piont;

extent Fun(void);
extent int a;全局變量和函數的定義不能出現在*.h文件裡。例如下面的代碼不能包含在頭文件:

int a;
void Fun1(void)
{
a++;
}

int a;
void Fun1(void)
{
a++;
}


2. 頭文件中不能包本地數據(模塊自己使用的數據或函數,不被其他模塊使用)。

這一點相當於面向對象程序設計裡的私有成員,即只有模塊自己使用的函數,數據,不要用extern在頭文件裡聲明,只有模塊自己使用的宏,常量,類型也不要在頭文件裡聲明,應該在自己的*.c文件裡聲明。

3. 含一些需要使用的聲明。在頭文件裡聲明外部需要使用的數據,函數,宏,類型。

4. 防止被重復包含。使用下面的宏防止一個頭文件被重復包含。

#ifndef MY_INCLUDE_H
#define MY_INCLUDE_H
<頭文件內容>
#endif

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-10/108356p2.htm

Copyright © Linux教程網 All Rights Reserved