原创 C语言头文件

2010-1-5 16:55 2995 10 10 分类: MCU/ 嵌入式
 在C语言的里,每个C文件是一个模块,头文件为使用这个模块的用户提供接口,用户只要包含相应的头文件就可以使用在这个头文件中暴露的接口。理想的情况下,一个可执行的模块提供一个公开的接口,即使用一个*.h文件暴露接口,但是,有时候,一个模块需要提供不止一个接口,这时,就要为每个定义的接口提供一个公开的接口。
 接口是指一个功能模块暴露出来的,提供给其他模块的访问具体功能的方法。根据C语言的特点,使用*.c文件实现模块的功能,使用*.h文件暴露单元的接口,在*.h文件里声明外部其他模块可能是用的
函数,数据类型,全局变量,类型定义,宏定义和常量定义.外部模块只需包含*.h文件就可以使用相应的功能.

 根据C语言的特点,并借鉴一些成熟软件项目代码,总结C项目中代码文件组织的基本建议:      
    1,使用层次化和模块化的软件开发模型.每一个模块只能使用所在层和下一层模块提供的接口.      
    2,每个模块的文件包存在独立的一个文件夹中.通常情况下,实现一个模块的文件不止一个,这些相关的文件应该保  存在一个文件夹中.  
    3,用于模块裁减的条件编译宏保存在一个独立的文件里,便于软件裁减.      
    4,硬件相关代码和操作系统相关代码与纯C代码相对独立保存,以便于软件移植.      
    5,声明和定义分开,使用*.h文件暴露模块需要提供给外部的函数,宏,类型,常量,全局变量,尽量做到模块对外部透明,用户在使用模块功能时不需要了解具体的实现,文件一旦发布,要修改一定要很慎重,      
    6,文件夹和文件命名要能够反映出模块的功能.      
    7,正式版本和测试版本使用统一文件,使用宏控制是否产生测试输出。      
    8,必要的注释不可缺少。 

  所有的头文件都建议参考以下的规则:
    1,   头文件中不能有可执行代码,也不能有数据的定义,只能有宏、类型(typedef,struct,union,menu),数据和函数的声明。全局变量和函数的定义不能出现在*.h文件里。
    2      头文件中不能包本地数据(模块自己使用的数据或函数,不被其他模块使用)。这一点相当于面向对象程序设计里的私有成员,即只有模块自己使用的函数、数据,不要用extent在头文件里声明,只有模块自己使用的宏,常量,类型也不要在头文件里声明,应该在自己的*.c文件里声明。      
    3,包含一些需要使用的声明。在头文件里声明外部需要使用的数据,函数,宏,类型。      
    4,防止被重复包含。使用下面的宏防止一个头文件被重复包含。      
    #ifndef       MY_INCLUDE_H      
    #define       MY_INCLUDE_H      
    <头文件内容 >      
    #endif      
    5,包含extern       "C",使的程序可以在C++编译器被编译      
    #ifdef       __cplusplus      
                    extern       "C"{      
    #endif      
    <函数声明 >      
    #ifdef       __cplusplus       <欢迎光临学网,点击这里查看更多文章教程 [1] [2] [3] [4]


br />                    }      
    #enfif      
  
   加extern       "C"声明后的编译和连接,强制C++连接器按照C编译器产生的符号_foo链接。      
  
   6,保证在使用这个头文件时,用户不用再包含使用此头文件的其他前提头文件,即要使用的头文件已经包含在此头文件里。例如:area.h头文件包含了面积相关的操作,要使用这个头文件不需同时包含了关于点操作的头文件piont.h。用户在使用area.h时不需要手动包含piont.h,因为我们已经在area.h中用#include       “point.h”包含了这个头文件。

  有一些头文件是为用户提供调用接口,这种头文件中声明了模块中需要给其他模块使用的函数和数据,鉴于软件质量上的考虑,处理参考以上的规则,用来暴露接口的头文件还需要参考更多的规则:      
    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,不要使用external。这是在*.h中使用的,可以被包含进来。      
    4,无论什么时候定义内部的对象,确保独立与其他执行文件。      
    5,这个文件里必须包含相应功能函数。      



PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
10
关闭 站长推荐上一条 /3 下一条