手机版
你好,游客 登录 注册
背景:
阅读新闻

C语言头文件组织

[日期:2014-10-23] 来源:Linux社区  作者: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

linux
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款