C语言的著作中,至今还没发现把.h文件的用法写的透彻的。在实际应用中也只能依葫芦画瓢,只知其然不知其所以然,甚是郁闷!闲来无事,便将搜集网络的相关内容整理一下,以便加深自己的理解

理论概述:
.h中一般放的是同名.c文件中定义的变量、数组、函数的声明,需要让.c外部使用的声明。

1)h文件作用:

1.方便开发:包含一些文件需要的共同的常量,结构,类型定义,函数,变量申明;

  2. 使函数的作用域从函数声明的位置开始,而不是函数定义的位置(实践总结)

  3 .提供接口:对一个软件包来说可以提供一个给外界的接口(例如: stdio.h)。

2)h文件里应该有什么:常量,结构,类型定义,函数,变量申明。

3)h文件不应该有什么:变量定义, 函数定义。

4)extern问题:
  1.对于变量需要extern;

  2.对于函数不需要因为函数的缺省状态是extern的.如果一个函数要改变为只在文件内可见,加static。

5)include包含问题:虽然申明和类型定义可以重复,不过推荐使用条件编译。
  #ifndef _FILENAME_H, 
  #define _FILENAME_H
  ……

  #endif

实践总结:

先看最简单的程序:hello world


  1. 1 /*test1.c*/
  2. 2 main()
  3. 3 {
  4. 4   printf("Hello World!\n");
  5. 5 }

注意,test1中并没有.h文件,编译可以顺利通过。把程序做下改动,下面这个:


  1. 1 /*test2.c*/
  2. 2 prtstr()
  3. 3 {
  4. 4   printf("Hello World!\n");
  5. 5 }
  6. 6 main()
  7. 7 {
  8. 8 prtstr();
  9. 9 }

test2.c中还是没有.h文件,编译仍可以顺利通过。再把程序改动下:


  1. 1 /*test3.c*/
  2. 2 main()
  3. 3 {
  4. 4   prtstr();
  5. 5 }
  6. 6
  7. 7 prtstr()
  8. 8 {
  9. 9   printf("Hello World!\n");
  10. 10 }

test3.c中仍然没有.h文件,编译失败→_→。难道函数的位置影响编译的过程?现在我们来熟悉一下C语言中的概念:作用域。

  我们在这里只讲述与.h文件相关的顶层作用域, 顶层作用域就是从声明点延伸到源程序文本结束, 就prtstr()这个函数来说,他没有单独的声明,只有定义,那么就从他定义的行开始,到文件结束, 也就是说,在test2.c的main()函数的引用点上,已经是他的作用域。 test3.c的main()函数的引用点上,还不是他的作用域,所以会编译出错. 这种情况怎么办呢? 有两种方法 ,一个就是让我们回到test2.c, 顺序对我们来说没什么, 谁先谁后不一样呢,只要能编译通过,程序能运行, 就让main()文件总是放到最后吧。那就让我们来看另一个例程,让我们看看这个方法是不是在任何时候都会起作用.


  1. /*test4.c*/
  2. 2 play2()
  3. 3 {
  4. 4 play1();
  5. 5 }
  6. 6
  7. 7 play1()
  8. 8 {
  9. 9 play2();
  10. 10 }
  11. 11
  12. 12 main()
  13. 13 {
  14. 14 play1();
  15. 15 }

这就是经常用到的一种算法, 函数嵌套。play1 和play2 这两个函数哪个放到前面呢?这时就需要我们来使用第二种方法,使用声明.


  1. 1 /*test5.c*/
  2. 2 play1();
  3. 3 play2();
  4. 4
  5. 5 play2()
  6. 6 {
  7. 7   play1();
  8. 8 }
  9. 9   play1()
  10. 10 {
  11. 11   play2();
  12. 12 }
  13. 13 main()
  14. 14 {
  15. 15   play1();
  16. 16 }

一个大型的软件项目,可能有几千个,上万个 play, 而不只是 play1,play2这么简单, 这样就可能有 N 个类似 play1(); play2(); 这样的声明, 这个时候就需要我们想办法把这样的 play1(); play2(); 另行管理, 而不是把他放在.c文件中, 于是.h 文件出现了.


  1. 1 /*test.h */
  2. 2 play1();
  3. 3 play2();
  4. 4 /* test6.C */
  5. 5 #include “test.h”
  6. 6 play2()
  7. 7 {
  8. 8   play1();
  9. 9 }
  10. 10 play1();
  11. 11 {
  12. 12   play2();
  13. 13 }
  14. 14 main()
  15. 15 {
  16. 16   play1();
  17. 17 }

上面是.h文件的最基本的功能。

c头文件(.h)的作用的更多相关文章

  1. 头文件.h的作用

    参考链接http://www.cnblogs.com/webcyz/archive/2012/09/16/2688035.html懒得复制过来

  2. [转]extern与头文件(*.h)的区别和联系

    用#include可以包含其他头文件中变量.函数的声明,为什么还要extern关键字? 如果我想引用一个全局变量或函数a,我只要直接在源文件中包含#include<xxx.h> (xxx. ...

  3. extern与头文件(*.h)的区别和联系

    原文网址为:http://lpy999.blog.163.com/blog/static/117372061201182051413310/ 个人认为有一些道理:所以转过来学习了. 用#include ...

  4. 浅谈头文件(.h)和源文件(.cpp)的区别

    浅谈头文件(.h)和源文件(.cpp)的区别 本人原来在大一写C的时候,都是所有代码写在一个文件里一锅乱煮.经过自己开始写程序之后,发现一个工程只有一定是由多个不同功能.分门别类展开的文件构成的.一锅 ...

  5. C++中的头文件(.h)和源文件(.cpp)都应该写什么?

    头文件(.h):写定义和声明写类的声明(包括类里面的成员和方法的声明).函数原型.#define常数等,但是一般来说不写具体的实现.注意: 1.在写头文件的时候需要注意,在开头和结尾处必须按照如下样式 ...

  6. 头文件 .h 与源文件 .ccp 的区别

    .h 文件一般是用来定义的,比如定义函数.类.结构体等: .cpp 文件则是对头文件的定义进行实现. include .h文件,可以调用你声明的函数.类等.当然,比较简单的类.函数,你也可以直接在头文 ...

  7. [C++] C语言及C++语言中包含的头文件名称,及作用

    头文件主目录include 头文件目录中总共有32个.h头文件.其中主目录下有13个,asm子目录中有4个,linux子目录中有10个,sys子目录中有5个.这些头文件各自的功能如下,具体的作用和所包 ...

  8. [C] 如何使用头文件 .h 编译 C 源码

    在 C 语言中,头文件或包含文件通常是一个源代码文件,程序员使用编译器指令将头文件包含进其他源文件的开始(或头部),由编译器在处理另一个源文件时自动包含进来. 一个头文件一般包含类.子程序.变量和其他 ...

  9. C++/C头文件 .h和 .c

    在C语言家族程序中,头文件被大量使用.一般而言,每个C++/C程序通常由头文件(header files)和定义文件(definition files)组成.头文件作为一种包含功能函数.数据接口声明的 ...

随机推荐

  1. [React] Render Text Only Components in React 16

    In this session we create a comment component to explore how to create components that only render t ...

  2. C# foreach 循环遍历数组

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  3. background-size在PC端和移动端使用媒体查询的不同

    1.PC端background-size:100%:是展现原图的大小. 2.使用媒体查询的移动端的background-size:100%:是根据内容的高度自动拉伸高度的.

  4. python序列中是否包含某个元素

    http://outofmemory.cn/code-snippet/9098/python-list-contains-with-in-not-in theList = ['a','b','c'] ...

  5. loadrunner11 +Win7 + 支持ie9,录制成功

    loadrunner11 支持ie9,录制成功 中文例子: https://wenku.baidu.com/view/1123925377232f60ddcca149.html http://blog ...

  6. 【CS Round #43 D】Bad Triplet

    [链接]点击打开链接 [题意] 给你n个点m条边的无权无向联通图; 让你找3个点A,B,C 使得A->B=B->C=A->C 这里X->Y表示点X到点Y的最短路长度. [题解] ...

  7. ASM学习笔记--ASM 4 user guide 第二章要点翻译总结

    参考:ASM 4 user guide 第一部分 core API 第二章  类 2.1.1概观 编译后的类包括: l  一个描述部分:包括修饰语(比如public或private).名字.父类.接口 ...

  8. [寒江孤叶丶的Cocos2d-x之旅_36]用LUA实现UTF8的字符串基本操作 UTF8字符串长度,UTF8字符串剪裁等

    原创文章,欢迎转载,转载请注明:文章来自[寒江孤叶丶的Cocos2d-x之旅系列] 博客地址:http://blog.csdn.net/qq446569365 一个用于UTF8字符串操作的类.功能比較 ...

  9. amazeui学习笔记--css(常用组件4)--关闭按钮Close

    amazeui学习笔记--css(常用组件4)--关闭按钮Close 一.总结 1.关闭按钮基本用法:关闭按钮样式,可以结合其他不同组件使用.对 <a> 或者 <button> ...

  10. MySQL參数binlog-do-db对binlogs写入的影响

    1. 环境描写叙述 目的:当数据库中设置了binlog-do-db时.在不同的binlog_format=statement | row | mixed 下对binlog的写入影响,这个在主从复制中会 ...