`
- 浏览:
315594 次
-
其实要理解C文件与头文件有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程:1.预处理阶段2.词法与语法分析阶段3.编译阶段,首先编译成纯汇编语句,再将之汇编成跟CPU相关的二进制码,生成各个目标文件4.连接阶段,将各个目标文件中的各段代码进行绝对地址定位,生成跟特定平台相关的可执行文件,当然,最后还可以用objcopy生成纯二进制码,也就是去掉了文件格式信息编译器在编译时是以C文件为单位进行的,也就是说如果你的项目中一个C文件都没有,那么你的项目将无法编译,连接器是以目标文件为单位,它将一个或多个目标文件进行函数与变量的重定位,生成最终的可执行文件,在PC上的程序开发,一般都有一个main函数,这是各个编译器的约定,当然,你如果自己写连接器脚本的话,可以不用main函数作为程序入口!!!!有了这些基础知识,再言归正传,为了生成一个最终的可执行文件,就需要一些目标文件,也就是需要C文件,而这些C文件中又需要一个main函数作为可执行程序的入口,那么我们就从一个C文件入手,假定这个C文件内容如下:#include<stdio.h>#include"mytest.h"intmain(intargc,char**argv){test=25;printf("test.................%d\n",test);}头文件内容如下:inttest;现在以这个例子来讲解编译器的工作: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标准,就算不看人家的头文件,你一样可以知道怎么使用
分享到:
Global site tag (gtag.js) - Google Analytics
相关推荐
C语言中,.h和.c文件是两个重要的文件类型,它们之间有着紧密的联系。在编译过程中,编译器会对C文件和头文件进行处理,生成目标文件,然后连接生成可执行文件。了解C文件和头文件的解析过程对于理解C语言的编译机制...
首先,让我们理解TWI和I²C的区别与联系。TWI是Atmel公司对I²C协议的实现,它们本质相同,都是由飞利浦(现NXP半导体)开发的一种同步串行通信协议。I²C协议允许微控制器与各种外设,如传感器、显示模块、实时时钟...
### H LIB DLL 文件的区别与联系 #### 概述 在软件开发过程中,程序员经常会接触到`.h`、`.lib`和`.dll`等不同类型的文件。这些文件分别在编译、链接以及运行时扮演着不同的角色。理解它们之间的区别与联系对于...
- **标准版本**:随着C语言的普及,先后出现了多个标准版本,如ANSI C (1989)、ISO C (1990)、C99、C11等,这些标准规范了C语言的语法和特性,提高了语言的一致性和可靠性。 #### 4. C语言的特点 - **结构化编程**...
RBSP、SODB、EBSP 三者的区别和联系 * SODB:最原始的编码数据,没有任何附加数据 * RBSP:在 SODB 的基础上加了 rbsp_stop_ont_bit(bit 值为 1)并用 0 按字节补位对齐 * EBSP:在 RBSP 的基础上增加了防止伪起始...
### C语言和C++在声明和定义之间的区别 在编程领域,尤其是在学习和使用C语言与C++时,理解和区分“声明”与“定义”的概念至关重要。这两种语言虽然有着密切的联系,但在处理声明和定义方面存在一些重要的差异。...
通过对“单轴机械手C14H.pdf”的分析,我们可以了解到这款机械手具备较高的定位精度和稳定性,适用于多种应用场景。在选择和使用过程中需要注意行程限制、共振风险以及具体的使用条件等因素,以确保机械手能够稳定...
根据给定的文件信息,我们将深入探讨"cputs"函数与"puts"函数之间的区别与联系,包括它们的定义、用途以及性能方面的差异。通过对比分析,我们能够更好地理解这两种函数的特点,并在实际编程中做出更合理的选择。 #...
9. 头文件的概念:在C语言中,扩展名为.h的文件称为头文件,常用于组织C标准函数库中的函数。 10. 注释语句的作用:注释语句不会增加编译结果的复杂性,因为它们在预处理阶段被删除。 11. 变量声明的含义:声明...
**winhttp与WinInet的区别与联系** - **性能与安全性**: `winhttp`设计为面向服务器和高性能应用,提供了更好的安全性和性能优化,支持HTTP/1.1和部分HTTP/2协议。而`WinInet`则更适合用户交互的客户端应用程序,它...
10. CPM1A与CP1E扩展模块的区别:两者扩展模块的I/O点数、功能和物理尺寸可能不同,不保证完全兼容。 11. CP1H模拟量输入/输出分布:模拟量I/O分布在特定的I/O地址范围内,具体可在用户手册中查找。 12. CP1H模拟...
本文将详细介绍如何在H3C设备上配置AAA、RADIUS以及TACACS+,并探讨它们之间的区别与联系。 #### AAA认证架构 AAA是一个综合性的安全框架,用于控制用户对网络资源的访问权限。它由三个主要部分组成: 1. **认证...
他们可以从中了解到DVB-H如何实现高效的移动电视广播,以及与其它DVB标准(如DVB-T、DVB-S和DVB-C)的区别和联系。同时,由于DVB-H已经不再新,学习这些资料也能帮助我们理解数字广播技术的发展历程和未来趋势。
根据提供的文件信息,“c和指针课后题答案(完整版).pdf”是一份关于C语言与指针的教程及课后习题解答文档。该文档涵盖了从基础概念到高级主题的各种章节,旨在帮助读者更好地理解和掌握C语言中的指针应用。 ### 一...
10. **C与C++的联系和区别**:由于C++是在C语言基础上发展起来的,了解两者之间的相似性和差异性,可以帮助开发者更好地选择和运用这两种语言。 总的来说,《C语言四经典》不仅提供了C语言的全面教程,还可能包含了...
4. Schema与Database的区别与联系: 在GaussDB 200中,Schema和Database都可以实现资源隔离。Database之间无法直接访问,但可以通过权限授予访问数据。Schema与用户紧密相关,通过权限控制语法可以实现不同用户对...
`#include <file.h>`与`#include "file.h"`的区别 - `#include <file.h>`:此形式通常用于包含标准库头文件。编译器会在标准系统目录下搜索指定的文件。 - `#include "file.h"`:此形式用于包含用户自定义的头文件...