一、全局变量单独编写(很值得借鉴)。

一般习惯将不同功能模块放到一个头文件和一个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语言头文件组织的更多相关文章

  1. C语言头文件组织与包含原则

    转自:http://www.cnblogs.com/clover-toeic/p/3728026.html 说明 本文假定读者已具备基本的C编译知识. 如非特殊说明,文中“源文件”指*.c文件,“头文 ...

  2. C语言头文件

    最近在工作当中遇到了一点小问题,关于C语言头文件的应用问题,主要还是关于全局变量的定义和声明问题.学习C语言已经有好几年了,工作使用也近半年了,但是对于这部分的东西的确还没有深入的思考过.概念上还是比 ...

  3. C语言头文件的使用(转载)

    C语言头文件的使用 ——by janders 转载请注名作者和出处,谢谢! C语言中的.h文件和我认识由来已久,其使用方法虽不十分复杂,但我却是经过了几个月的“不懂”时期,几年的“一知半解”时期才逐渐 ...

  4. [转载]C语言头文件的作用

    最近在工作当中遇到了一点小问题,关于C语言头文件的应用问题,主要还是关于全局变量的定义和声明问题.学 习C语言已经有好几年了,工作使用也近半年了,但是对于这部分的东西的确还没有深入的思考过.概念上还是 ...

  5. c语言头文件中定义全局变量的问题

    c语言头文件中定义全局变量的问题 (转http://www.cnblogs.com/Sorean/) 先说一下,全局变量只能定义在 函数里面,任意函数,其他函数在使用的时候用extern声明.千万不要 ...

  6. 嵌入式C语言头文件的建立与使用

    如何正确编写 C 语言头文件和与之相关联的 c 源程序文件,这首先就要了解它们的各自功能. 要理解 C 文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程. 一般说来编译器会做以下几 ...

  7. 51单片机C语言学习笔记6:51单片机C语言头文件及其使用

    很多初学单片机者往往对C51的头文件感到很神秘,而为什么要那样写,甚至有的初学者喜欢问,P1口的P为什么要大写,不大写行不行呢?其实这个是在头文件中用sfr定义的,现在定义好了的是这样的 sfr P1 ...

  8. C++标准库头文件名字和C语言头文件名字的区别

    1.C++版本的C标准库头文件,一般是cname,而C语言头文件一般是name.h 2.命名为cname的头文件中定义的名字都是从std中来的,而如果是name.h则不是这样的. 3.与是用name. ...

  9. C语言头文件、库文件的查找路径

    在 程序设计中,文件包含是很有用的.一个大的程序可以分为多个模块,由多个程序员分别编程.有些公用的符号常量或宏定义等可单独组成一个文件,在其它文件的开头用包含命令包含该文件即可使用.这样,可避免在每个 ...

随机推荐

  1. 再一次强调,ORACLE外键必须加索引

    外键加索引是常识,必须牢记.本来不想写这样的简单案例.可是连续遇到好几起外键不加索引导致性能问题,所以还是写一下. 一个兄弟问我 delete from Sa_Sales_Comm_Detail s  ...

  2. [Regular Expressions] Find Groups of Characters, and ?:

    We'll capture groups of characters we wish to match, use quantifiers with those groups, and use refe ...

  3. configure交叉编译

    今天在交叉编译时犯了一个错误,纠结了好久,曾经交叉编译器的前缀基本上都是用arm-linux-,这次换了一个新环境是arm-none-linux-gnueabi-,于是想当然的把configure中的 ...

  4. oracle函数Lpad与Rpad

    函数介绍 lpad函数从左边对字符串使用指定的字符进行填充.从其字面意思也可以理解,l是left的简写,pad是填充的意思,所以lpad就是从左边填充的意思. 语法格式如下: lpad( string ...

  5. mycat源码分析

    http://www.cnblogs.com/fernandolee24/p/5196367.html

  6. (转)浅谈ASP.NET报表控件

    项目中有报表图形化的需求, 于是开始在网上找第三方chart控件.因时间紧迫,大至确定了几个候选:一.Office带的OWC控件:二.ComponentOne:三.Web Chart.本文将讲解ASP ...

  7. IE iframe 中 js 的 cookie 读写不到的解决办法

    1.看这里(改服务器配置) http://www.cr173.com/html/16696_1.html 2.使用object模拟iframe,不使用iframe框架 <html> < ...

  8. NSData、NSString 、 NSFileManager

      1 NSData和NSMutableData的基本使用 1.1 问题 NSData类是IOS提供的用于以二进制的形式操作文件数据的类,NSData有两个常用的属性length和bytes,leng ...

  9. KMP与扩展KMP

    原文转自:http://www.cppblog.com/MatoNo1/archive/2011/04/17/144390.aspx KMP:给出两个字符串A(称为模板串)和B(称为子串),长度分别为 ...

  10. Tomcat学习笔记 - 错误日志 - NetBeans配置tomcat出错情况总结 -- 部署错误: 启动 Tomcat 失败。-- '127.0.0.1' 不是内部或外部命令,也不是可运行的程序

    真的管用,不知道为啥管用.转载自:http://blog.sina.com.cn/s/blog_709548200102vgy4.html 问题描述: 新安装的NetBeans8.0.2,安装过程中还 ...