`
wangleide414
  • 浏览: 608605 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

C语言中的h文件和c文件

 
阅读更多

从基础看起,.c中主要包括你要实现的函数,变量定义等,.h中包括一些函数和变量声明,以及宏定义; 
在多个.c文件中你可以#include "xxx.h ",然后是用头文件中的函数或变量

 

简单的说.c生成obj文件会分配空间 .h则不会

 

其实要理解C文件与头文件有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 
1.预处理阶段 
2.词法与语法分析阶段 
3.编译阶段,首先编译成纯汇编语句,再将之汇编成跟CPU相关的二进制码,生成各个目标文件 
4.连接阶段,将各个目标文件中的各段代码进行绝对地址定位,生成跟特定平台相关的可执行文件,当然,最后还可以用objcopy生成纯二进制码,也就是去掉了文件格式信息 

编译器在编译时是以C文件为单位进行的,也就是说如果你的项目中一个C文件都没有,那么你的项目将无法编译,连接器是以目标文件为单位,它将一个或多个目标文件进行函数与变量的重定位,生成最终的可执行文件,在PC上的程序开发,一般都有一个main函数,这是各个编译器的约定,当然,你如果自己写连接器脚本的话,可以不用main函数作为程序入口!!!! 

有了这些基础知识,再言归正传,为了生成一个最终的可执行文件,就需要一些目标文件,也就是需要C文件,而这些C文件中又需要一个main函数作为可执行程序的入口,那么我们就从一个C文件入手,假定这个C文件内容如下: 
#include   <stdio.h> 
#include   "mytest.h " 

int   main(int   argc,char   **argv) 

  test   =   25; 
  printf( "test.................%d\n ",test); 


头文件内容如下: 
int   test; 

现在以这个例子来讲解编译器的工作: 
1.预处理阶段:编译器以C文件作为一个单元,首先读这个C文件,发现第一句与第二句是包含一个头文件,就会在所有搜索路径中寻找这两个文件,找到之后,就会将相应头文件中再去处理宏,变量,函数声明,嵌套的头文件包含等,检测依赖关系,进   行宏替换,看是否有重复定义与声明的情况发生,最后将那些文件中所有的东东全部扫描进这个当前的C文件中,形成一个中间“C文件” 
2.编译阶段,在上一步中相当于将那个头文件中的test变量扫描进了一个中间C文件,那么test变量就变成了这个文件中的一个全局变量,此时就将所有这个中间C文件的所有变量,函数分配空间,将各个函数编译成二进制码,按照特定目标文件格式生成   目标文件,在这种格式的目标文件中进行各个全局变量,函数的符号描述,将这些二进制码按照一定的标准组织成一个目标文件 
3.连接阶段,将上一步成生的各个目标文件,根据一些参数,连接生成最终的可执行文件,主要的工作就是重定位各个目标文件的函数,变量等,相当于将个目标文件中的二进制码按一定的规范合到一个文件中 

再回到C文件与头文件各写什么内容的话题上: 
理论上来说C文件与头文件里的内容,只要是C语言所支持的,无论写什么都可以的,比如你在头文件中写函数体,只要在任何一个C文件包含此头文件就可以将这个函数编译成目标文件的一部分(编译是以C文件为单位的,如果不在任何C文件中包含此头文件的话,这段代码就形同虚设),你可以在C文件中进行函数声明,变量声明,结构体声明,这也不成问题!!!那为何一定要分成头文件与C文件呢?又为何一般都在头件中进行函数,变量声明,宏声明,结构体声明呢?而在C文件中去进行变量定义,函数实现呢??原因如下: 

 

1.如果在头文件中实现一个函数体,那么如果在多个C文件中引用它,而且又同时编译多个C文件,将其生成的目标文件连接成一个可执行文件,在每个引用此头文件的C文件所生成的目标文件中,都有一份这个函数的代码,如果这段函数又没有定义成局部   函数,那么在连接时,就会发现多个相同的函数,就会报错 

 

2.如果在头文件中定义全局变量,并且将此全局变量赋初值,那么在多个引用此头文件的C文件中同样存在相同变量名的拷贝,关键是此变量被赋了初值,所以编译器就会将此变量放入DATA段,最终在连接阶段,会在DATA段中存在多个相同的变量,它无法   将这些变量统一成一个变量,也就是仅为此变量分配一个空间,而不是多份空间,假定这个变量在头文件没有赋初值,编译器就会将之放入BSS段,连接器会对BSS段的多个同名变量仅分配一个存储空间 


3.如果在C文件中声明宏,结构体,函数等,那么我要在另一个C文件中引用相应的宏,结构体,就必须再做一次重复的工作,如果我改了一个C文件中的一个声明,那么又忘了改其它C文件中的声明,这不就出了大问题了,程序的逻辑就变成了你不可想象   的了,如果把这些公共的东东放在一个头文件中,想用它的C文件就只需要引用一个就OK了!!!这样岂不方便,要改某个声明的时候,只需要动一下头文件就行了 
4.在头文件中声明结构体,函数等,当你需要将你的代码封装成一个库,让别人来用你的代码,你又不想公布源码,那么人家如何利用你的库呢?也就是如何利用你的库中的各个函数呢??一种方法是公布源码,别人想怎么用就怎么用,另一种是提供头   文件,别人从头文件中看你的函数原型,这样人家才知道如何调用你写的函数,就如同你调用printf函数一样,里面的参数是怎样的??你是怎么知道的??还不是看人家的头文件中的相关声明啊!!!当然这些东东都成了C标准,就算不看人家的头文   件,你一样可以知道怎么使用 

分享到:
评论

相关推荐

    C语言实现h264保存为mp4文件

    通过阅读和理解源代码,你可以看到如何使用C语言处理二进制数据,如何解析和重组H264数据,以及如何构建符合MP4规范的文件结构。 在实际应用中,这个过程可能涉及到更复杂的情况,比如处理多路视频流、添加音频流、...

    C语言读取dat文件

    在C语言中,读取和写入`.dat`文件是一项基本操作,通常用于存储和检索非结构化的数据。`.dat`文件本身并没有特定的格式,它只是一个二进制或文本文件,可以按照开发者的需求来组织数据。下面我们将深入探讨如何在...

    C语言读取CSV文件

    此外,如果CSV文件中存在包含逗号的字段(如逗号引号包围的文本),则需要更复杂的解析逻辑,可能需要用到正则表达式库或第三方CSV解析库。 在提供的`ReadCSVFile`源码中,作者可能已经封装了这些功能,包括对复杂...

    SVM在c语言中的.h文件

    SVM在c语言中的.h文件SVM在c语言中的.h文件SVM在c语言中的.h文件

    C语言读取和写入dat文件 代码

    在C语言中,读取和写入`.dat`文件是一项基本操作,通常用于存储和检索数据。`.dat`文件没有特定的格式,可以是任何类型的数据。本篇将详细讲解如何使用C语言进行读写操作,并结合正弦函数的计算,以`mysin`为例,...

    Linux C语言的配置文件操作库

    在Linux系统中,C语言作为底层编程的主要工具,其对配置文件的操作往往涉及到繁琐的文件I/O操作。然而,为了简化这一过程,开发者通常会利用特定的库来处理配置文件,比如读取、写入、解析键值对等。本文将深入探讨...

    纯C语言读写ini配置文件

    提供的两个`.mht`文件,`[ 永远的UNIX C源码通用C语言函数:文本文件有关操作,_CFG-_INI类配置文件读写 ].mht` 和 `[ 永远的UNIX C源码通用C语言函数:文本文件有关操作,_CFG-_INI类配置文件读写(对应_C的头文件 )...

    C语言中的文件操作

    下面将详细介绍一些常用的C语言文件操作函数和相关知识点。 1. 文件操作基础: 在C语言中,文件被看作是一系列字节序列。进行文件操作前,需要打开文件,完成后则需关闭文件。`fopen()`函数用于打开文件,它接受...

    C语言编程JPEG转.h文件ImageConverter565 BMP转565

    在图像处理领域,C语言也被用于编写各种工具和库,如本例中的"ImageConverter565",它是一个将图像格式转换为特定格式的程序,特别是将JPEG和BMP图像转换为565格式的头文件(.h文件)。 JPEG是一种常用的有损图像...

    C语言头文件(.h文件)的作用

    在这种情况下,我们可以使用头文件来定义和声明变量和函数,然后在不同的C语言文件中#include头文件,以便共享变量和函数。 例如,假设我们有一个数学函数库,包含了多个数学函数,我们可以在头文件中定义和声明...

    c语言中怎样把文本文件中的一列数导入程序中

    例如,在上面的代码中,我们使用main()函数作为程序入口,使用while()循环来读取文件中的字符,并使用if()语句来判断字符是否满足特定的条件。 5. 文件系统 在C语言中,文件系统是通过文件系统函数实现的。例如,...

    C语言实现从文件中读取数据

    本文将深入探讨如何使用C语言来实现从文件中读取数据。我们将涵盖基本的文件操作,包括打开、读取、关闭文件以及处理可能出现的错误。 首先,我们需要理解C语言中的文件流(file stream)概念。在C语言中,文件被...

    C语言读取和写入dat文件

    在C语言中,读取和写入数据文件是常见的任务,尤其当涉及到处理特定格式的文件,如dat文件时。dat文件通常被用作自定义数据存储,它们没有固定的文件结构,可以包含任何类型的数据。本教程将深入探讨如何使用C语言对...

    C语言中.h和.c文件解析

    在预处理阶段,`mytest.h`的内容会被插入到`mytest.c`中,使`test`变量成为`mytest.c`文件中的一部分。接下来,编译器会为`test`变量分配内存,并在编译阶段将其编译为二进制代码,最终在链接阶段与其他目标文件结合...

    C语言读取文件

    本文将深入探讨C语言如何读取文件,以及如何将读取的数据存储到另一个文件中。 首先,我们需要了解C语言中的文件操作函数。`fopen()`函数用于打开一个文件,`fclose()`用于关闭已打开的文件,`fread()`和`fwrite()`...

    H264视频流文件转flv文件源码实现(C语言,不用第三方库)

    H264视频流文件转flv文件源码实现(C语言,不用第三方库) H264视频流文件转flv文件源码实现(C语言,不用第三方库) H264视频流文件转flv文件源码实现(C语言,不用第三方库) 附加flv解析工具 附加flv解析工具 ...

    C语言中.h和.c文件解析.pdf

    C语言中.h和.c文件解析 在C语言编程中,`.h`文件和`.c`文件是两个非常重要的组成部分,理解这两个文件的作用和关系是编程的基础。本文将对C语言中`.h`文件和`.c`文件进行解析,并详细介绍编译器的工作过程。 首先...

    音频文件数组转成c语言的数组

    在给定的“test”文件中,如果这是一个音频文件,那么你需要使用上述方法进行处理。不过,没有提供具体的音频文件,无法给出详细的代码示例。如果你有具体的音频文件和更详细的需求,我可以提供更精确的帮助。

    c语言文件章节 学习c文件

    二是实现数据共享,不同程序可以访问同一个文件中的数据;三是持久保存程序运行过程中的中间数据或结果。 根据逻辑结构,文件主要分为记录文件和流式文件。记录文件由固定长度或可变长度的记录组成,而流式文件则由...

    c语言文件创建,删除等

    在C语言中,文件操作是程序设计中的重要组成部分。它允许程序员将数据写入文件,从文件读取数据,以及进行文件的创建、删除等管理操作。以下是对这些主题的详细解释: 1. **文件创建**: 在C语言中,`fopen()` ...

Global site tag (gtag.js) - Google Analytics