C语言头文件组织
一、全局变量单独编写(很值得借鉴)。
一般习惯将不同功能模块放到一个头文件和一个C文件中。
例如是写一些数学计算函数:
//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()
{
…
}
哪个C文件需要使用只需包含头文件mymath.h就可以了。
但是我认为上面的方法虽然好,但是上面定义全局变量的方式在比较大的工程中引起不便,一个
模块与其他模块的数据传递最好通过专有的函数进行,而不要直接通过数据单元直接传递(这是VC++的思想),因此不建议在模块的头文件中声明全局变量;
全局变量最好统一定义在一个固定的文件中,所以可以采用下面的方法:
定义一个Globel_Var.C文件来放全局变量,然后在与之相对应的Globel_Var.H文件中来声明全局变量
例如:
——————————————————————————————————
//Globel_Var.c
/*******定义本工程中所用到的全局变量*******/
int speed;
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.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.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()
{
…
}
——————————————————————————————————
这样即不会报错又可以轻松使用全局变量。
二、如果在全局变量前加入static或者const(隐式为static类型的变量)
如下
// 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;
全局变量和函数的定义不能出现在*.h文件里。例如下面的代码不能包含在头文件:
int a;
void Fun1(void)
{
a++;
}
2. 头文件中不能包本地数据(模块自己使用的数据或函数,不被其他模块使用)。
这一点相当于面向对象程序设计里的私有成员,即只有模块自己使用的函数,数据,不要用extern在头文件里声明,只有模块自己使用的宏,常量,类型也不要在头文件里声明,应该在自己的*.c文件里声明。
3. 含一些需要使用的声明。在头文件里声明外部需要使用的数据,函数,宏,类型。
4. 防止被重复包含。使用下面的宏防止一个头文件被重复包含。
#ifndef MY_INCLUDE_H
#define MY_INCLUDE_H
<头文件内容>
#endif
四、头文件编写参考更多的规则(暂时只能理解1、2、3、4)
有一些头文件是为用户提供调用接口,这种头文件中声明了模块中需要给其他模块使用的函数和数据,鉴于软件质量上的考虑,处理参考以上的规则,用来暴露接口的头文件还需要参考更多的规则:
1. 一个模块一个接口,不能几个模块用一个接口。
2. 文件名为和实现模块的c文件相同。abc.c--abc.h
3. 尽量不要使用extern来声明一些共享的数据。因为这种做法是不安全的,外部其他模块的用户可能不能完全理解这些变量的含义,最好提供函数访问这些变量。
4. 尽量避免包含其他的头文件,除非这些头文件是独立存在的。这一点的意思是,在作为接口的头文件中,尽量不要包含其他模块的那些暴露*.C文件中内容的头文件,但是可以包含一些不是用来暴露接口的头文件。
5. 不要包含那些只有在可执行文件中才使用的头文件,这些头文件应该在*.c文件中包含。这一点如同上一点,为了提高接口的独立性和透明度
6. 接口文件要有面向用户的充足的注释。从应用角度描述个暴露的内容。
7. 接口文件在发布后尽量避免修改,即使修改也要保证不影响用户程序。
五、多个代码文件使用一个接口文件(暂时不能完全理解)
这种头文件用于那些认为一个模块使用一个文件太大的情况。对于这种情况对于这种情况在参考上述建议后,也要参考以下建议。
1. 多个代码文件组成的一个模块只有一个接口文件。因为这些文件完成的是一个模块。
2. 使用模块下文件命名 <系统名> <模块名命名>
3. 不要滥用这种文件。
4. 有时候也会出现几个*.c文件用于共享数据的*.h文件,这种文件的特点是在一个*.c文件里定义全局变量,而在其他*.c文件里使用,要将这种文件和用于暴露模块接口的文件区别。
5. 一个模块如果有几个子模块,可以用一个*.h文件暴露接口,在这个文件里用#include包含每个子模块的接口文件。
还有一种头文件,说明性头文件,这种头文件不需要有一个对应的代码文件,在这种文件里大多包含了大量的宏定义,没有暴露的数据变量和函数。这些文件给出以下建议:
1. 包含一些需要的概念性的东西.
2. 命名方式,定义的功能.h
3. 不包含任何其他的头文件.
4. 不定义任何类型.
5. 不包含任何数据和函数声明.
上面介绍了C头文件的一些建议,下面介绍C代码文件*.c文件的一些建议,*.c文件是C语言中生成汇编代码和机器码的内容,要注意以下建议:
1.命名方式 模块名.c
2,用static修饰本地的数据和函数。
3,不要使用externa。这是在*.h中使用的,可以被包含进来。
4,无论什么时候定义内部的对象,确保独立与其他执行文件。
5,这个文件里必须包含相应功能函数。
结束语:上面介绍了一些C文件组织的建议,用于提高C语言项目的质量,在以后的C项目组织中,学习面向对象和COM的思想,将这些思想加入到C程序中,能够写出更高质量的代码。上面的建议在具体的项目里应该灵活运用。另外,C工程中经常有一些汇编代码文件,这些文件也要使有*.h头文件暴露其中的数据和函数,以便其他*.c文件包含使用。
转自:http://www.2cto.com/kf/201109/104897.html
点击打开链接
C语言头文件组织的更多相关文章
- C语言头文件组织与包含原则
转自:http://www.cnblogs.com/clover-toeic/p/3728026.html 说明 本文假定读者已具备基本的C编译知识. 如非特殊说明,文中“源文件”指*.c文件,“头文 ...
- C语言头文件
最近在工作当中遇到了一点小问题,关于C语言头文件的应用问题,主要还是关于全局变量的定义和声明问题.学习C语言已经有好几年了,工作使用也近半年了,但是对于这部分的东西的确还没有深入的思考过.概念上还是比 ...
- C语言头文件的使用(转载)
C语言头文件的使用 ——by janders 转载请注名作者和出处,谢谢! C语言中的.h文件和我认识由来已久,其使用方法虽不十分复杂,但我却是经过了几个月的“不懂”时期,几年的“一知半解”时期才逐渐 ...
- [转载]C语言头文件的作用
最近在工作当中遇到了一点小问题,关于C语言头文件的应用问题,主要还是关于全局变量的定义和声明问题.学 习C语言已经有好几年了,工作使用也近半年了,但是对于这部分的东西的确还没有深入的思考过.概念上还是 ...
- c语言头文件中定义全局变量的问题
c语言头文件中定义全局变量的问题 (转http://www.cnblogs.com/Sorean/) 先说一下,全局变量只能定义在 函数里面,任意函数,其他函数在使用的时候用extern声明.千万不要 ...
- 嵌入式C语言头文件的建立与使用
如何正确编写 C 语言头文件和与之相关联的 c 源程序文件,这首先就要了解它们的各自功能. 要理解 C 文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程. 一般说来编译器会做以下几 ...
- 51单片机C语言学习笔记6:51单片机C语言头文件及其使用
很多初学单片机者往往对C51的头文件感到很神秘,而为什么要那样写,甚至有的初学者喜欢问,P1口的P为什么要大写,不大写行不行呢?其实这个是在头文件中用sfr定义的,现在定义好了的是这样的 sfr P1 ...
- C++标准库头文件名字和C语言头文件名字的区别
1.C++版本的C标准库头文件,一般是cname,而C语言头文件一般是name.h 2.命名为cname的头文件中定义的名字都是从std中来的,而如果是name.h则不是这样的. 3.与是用name. ...
- C语言头文件、库文件的查找路径
在 程序设计中,文件包含是很有用的.一个大的程序可以分为多个模块,由多个程序员分别编程.有些公用的符号常量或宏定义等可单独组成一个文件,在其它文件的开头用包含命令包含该文件即可使用.这样,可避免在每个 ...
随机推荐
- Rhythmbox中文乱码解决的方法
转自:http://hi.baidu.com/morgensonne/item/3470aef58747abde6325d2d9 今天在网络上找到了一个比較好的解决Rhythmbox中文乱码的问题的方 ...
- Impala与Hive的比較
1. Impala架构 Impala是Cloudera在受到Google的Dremel启示下开发的实时交互SQL大数据查询工具,Impala没有再使用缓慢的Hive+MapReduce批 ...
- hadoop多文件输出
现实环境中,经常遇到一个问题就是想使用多个Reduce,可是迫于setup和cleanup在每个Reduce中会调用一次,仅仅能设置一个Reduce,无法是实现负载均衡. 问题,假设要在reduce中 ...
- T-SQL和PL/SQL 区别
结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库系统:同时也是数据库 ...
- JS中面向对象的,对象理解、构造函数、原型、原型链
6.1 理解对象 6.1.1 对象属性类型 ECMS属性有两种类型:数据属性和访问器属性 1 数据属性 [[configurable]] 表示能否通过Delete 删除属性从而从新定义属性,能否修改属 ...
- 装Oracle12C时遇到没有权限访问临时位置的解决方法
今天在装oracle12c是遇到了一个很奇怪的问题,显示是没有权限访问临时位置,可是我明明是用管理员的账号登陆的啊,最后在包姐的帮助下解决了,知其然,而我却不知其所以然.但还是把方法写下,希望能帮到一 ...
- 使用C#创建自定义背景色/形状的菜单栏与工具栏
C#对于菜单栏与工具栏都提供了统一的背景色,形状的渲染类,即ToolStripRenderer类,同时根据不同的情形,提供了多个继承类,分别是ToolStripProfessionalRender,T ...
- XML格式导出Excel
下面介绍一种导出Excel的方法: 此方法不需要在服务器上安装Excel,采用生成xml以excel方式输出到客户端,可能需要客户机安装excel,所以也不会有乱七八糟的权限设定,和莫名其妙的版本问题 ...
- Spark集群搭建简要
Spark集群搭建 1 Spark编译 1.1 下载源代码 git clone git://github.com/apache/spark.git -b branch-1.6 1.2 修改pom文件 ...
- java普通类如何得到spring中的bean类
在SSH集成的前提下.某些情况我们需要在Action以外的类中来获得Spring所管理的Service对象. 之前我在网上找了好几好久都没有找到合适的方法.例如: ApplicationContext ...