[重点!]头文件&源文件&编译&链接

C/C++支持分离式编译:一个程序可以分成多个部分保存在各个文件(头文件、源文件)中,在链接之前,各个文件(无论源文件还是头文件)是相互独立、没有关联的

分离式编译是指一个完整的程序或项目由若干个源文件共同实现,每个源文件单独编译生成目标文件,最后将该项目中的所有目标文件连接成一个单一的可执行文件的过程。

在这里插一嘴:

==#include==的作用

这是一个宏定义,众所周知,宏定义就是替换,比如a.cpp中要包含a.h,写作#include"a.h"

这一行就是将#include后的"a.h"替换为a.h中的所有代码

但这并不能说明a.cpp和a.h是有关联的,只是a.cpp中包含了a.h,包含并不意味着有关联

因为#incldue是宏定义,是替换,跟其他的宏定义一样,比如#define N 100

众所周知,头文件保存变量(自定义)和函数的声明,源文件保存变量和函数的定义(实现)

头文件的作用

C/C++编译采用的是分离编译模式。在一个项目中,有多个源文件存在,但是它们总会有一些相同的内容,比如用户自定义类型、全局变量、全局函数的声明等。将这些内容抽取出来放到头文件中,提供给各个源文件包含,就可以避免想相同内容的重复书写,提高编程效率和代码安全性。所以,设立头文件的目的主要是:提供全局变量、全局函数的声明或公用数据类型的定义,从而实现分离编译和代码复用。

概括的说,头文件有如下三个作用。

  1. 加强类型检查,提高类型安全性。 使用头文件,可有效地保证自定义类型的一致性。虽然,在语法上,同一个数据类型(如一个class)在不同的源文件中书写多次是允许的,程序员认为他们是同一个自定义类型,但是,由于数据类型不具有外部连接特性,编译器并不关心该类型的多个版本之间是否一致,这样有可能会导致逻辑错误的发生。
  2. 减少公用代码的重复书写,提高编程效率。 程序开发过程中,对某些数据类型或者接口进行修改是在所难免的,使用头文件,只需要修改头文件中的内容,就可以保证修改在所有源文件中生效,从而避免了繁琐易错的重复修改。
  3. 提供保密和代码重用的手段。 头文件也是C++代码重用机制中不可缺少的一种手段,在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制库即可。用户只需要按照头文件的接口声明来调用库函数,而不必关心接口的具体实现,编译器会从库中连接相应的实现代码。(封装性)

但是其实头文件和源文件并没有关联

比如在a.h中声明了一个类a,包含成员变量和成员函数的声明,在a.cpp中包含类a成员函数的定义(实现)

其实在编写的时候,a.h和a.cpp没有关联,编译器并不知道它俩的关系

a.cpp中对于类a的成员函数进行了定义,但a.cpp中并没有类a的声明

而a.h和a.cpp并没有关联,也就是说编译器不知道a.cpp中的类a在哪儿声明的,而类a如果没有声明,这就是一个错误

所以这就是为什么a.cpp一定要包含a.h

如果再有一个b.h和b.cpp以及一个包含main函数的main.cpp

如果b中想要使用类a,则在b.h中包含类a的声明和定义就可以

我们知道,main.cpp中想要使用某个现有的变量或者函数,只要包含对应的头文件就可以

那么是不是只需要在b.h中包含头文件a.h(#include"a.h)就可以的

这是不可以的,因为a.h和a.cpp是没有关联的:a.h中只有a的声明,没有a的定义

如果此时运行的话,在运行时会报错:缺少a的定义

但是如果不运行是不会报错的,因为a.h中虽然没有a的定义,但是有声明,并没有语法和逻辑错误

缺少a的定义是属于编译错误

正确的做法是b.h中包含a.cpp而不是a.h

因为a.cpp中是对类a的成员函数的定义,而a.cpp中又包含a.h

话说回来,为什么main.cpp中可以包含头文件,不用包含源文件?因为链接

编译

编译是对项目中所有的源文件(注意只是源文件,不是头文件)进行编译,将它们“翻译”成为机器能识别的机器语言,每个源文件被编译后会生成一个对应的目标文件,里面是源文件代码被翻译成的机器语言

头文件是不进行编译的,理由在下面

众所周知,main函数是程序的入口,要想执行程序,就要执行main函数

含有main函数的源文件,在这里我叫它main文件吧

main文件也是源文件,也和其他源文件一样,在编译的时候会进行编译

main文件中会包含头文件

可是头文件中只有声明,没有定义,那怎么能用对应的变量和函数呢

链接

在编译之后,每个源文件都会生成一个目标文件

在执行程序时,编译之后,进行链接

main文件中含有头文件,链接就是通过头文件,找到对应的实现头文件中声明的内容的源文件,再找到这些源文件的目标文件,将这些目标文件跟main文件的目标文件“链接”起来,形成一个结合体打包起来------可执行文件

所以,因为有链接这一步,main文件中只包含头文件就行,因为链接时可以找到对应的源文件

而且链接是对于main文件而言的,也就是这一步只能用在main文件上,将main文件的目标文件 与 main文件包含的头文件对应的源文件的目标文件 结合起来

跟编译不同,一般的源文件不执行链接这个步骤,因为这是没有意义的,只有main文件是程序的接口

总结

只有main文件才能只包含头文件,不包含源文件

只有库函数或者库里的类被一般源文件调用的时候,一般的源文件可以只包含对应的库头文件

一般的源文件想要调用别的 自定义的类 或者 自定义的函数 的时候,要在其头文件中包含对应的源文件而不是头文件

源文件如何根据#include来包含头文件:

  1. 系统库自带的头文件(库文件)用尖括号括起来,这样编译器会在系统库文件目录下查找。
  2. 用户自定义的文件用双引号括起来,编译器首先会在用户目录下查找,然后在到C++安装目录(比如VC中可以指定和修改库文件查找路径,Unix和Linux中可以通过环境变量来设定)中查找,最后在系统文件中查找。

[重点!]头文件源文件编译链接相关推荐

  1. 头文件源文件定义标准

    头文件源文件定义标准 @TOC- 前言 头文件源文件定义标准(自己理解) Function1.h #pragma once #ifndef ADI_HEADER #define ADI_HEADERe ...

  2. Visual Studio 2022 自定义头文件源文件切换快捷键

    Visual Studio 2022 自定义头文件源文件切换快捷键 修改步骤 注意事项 修改步骤 废话不多说,直接上流程. (1)工具 -> 选项 -> 环境 -> 键盘 -> ...

  3. 关于c++源文件与头文件的编译规则总结

    C++语言支持"分别编译"(separate compilation).也就是说,一个程序所有的内容,可以分成不同的部分分别放在不同的.cpp文件里. .cpp文件被称作C++源文 ...

  4. mp4文件时长 c++源码_【C语言】如何使用头文件 .h 编译 C 源码!so easy!

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

  5. c++头文件|源文件详解

    一.C++ 编译模式 通常,在一个 C++ 程序中,只包含两类文件―― .cpp 文件和 .h 文件.其中,.cpp 文件被称作 C++ 源文件,里面放的都是 C++ 的源代码:而 .h 文件则被称作 ...

  6. 类型重定义 头文件预编译设置

    这是一个比较常用的C/C++杂注,只要在头文件的最开始加入这条杂注,就能够保证头文件只被编译一次.在编写头文件的时候,如果没有加上这一句,编译器可能会编译多次这个头文件.VS编译器会报出这个头文件 里 ...

  7. linux头文件怎么编译,microsoft编译器怎么使用Linux头文件

    microsoft编译器如何使用Linux头文件? #include #include #include #include #include #include #include #include #i ...

  8. ccs中c语言定义布尔常量,ccs库里面有变量的定义,我在添加了头文件后编译显示没有定义变量呢...

    用CCS6.0编译总是出类似的错误,最近写一个I2C的代码一直弄不好,请大神们知道一下吧这个是库里面的例子加载编译出来都是错 #include #include #include #include & ...

  9. 解决方案资源管理器中没有头文件源文件

    转自:http://blog.csdn.net/wsj998689aa/article/details/40051287 我们操作VS的时候,正常情况下,解决方案窗口中,项目内文件的布局如下: 可是, ...

最新文章

  1. 心辽阔了,人生才能辽阔
  2. JavaScript常用内置对象之Array
  3. 语言统计学中的几个定律,可作为设计检索的参考
  4. JVM参数调优详细过程
  5. python写二分法_Python实现二分法算法实例
  6. React Native与React的关系及特点
  7. halcon识别ocr汉字_手写汉字识别——手写文本快速电子化的好方法
  8. xml 和android脚本之家,Android开发之XML文件解析的使用
  9. C# 直接选择排序(史上最清晰,最通俗)
  10. Kotlin的互操作——Kotlin与Java互相调用
  11. V4L2像素格式及其对应的含义
  12. 回文字符串判断python实现
  13. 中国各民族名称的罗马字母拼写法和代码-GBT 3304-1991
  14. 华师大的计算机专业属于提前批吗,关于华师大、上师大提前批的问题
  15. epr系统服务器配置,erp系统云服务器配置要求
  16. 动态监控zookeeper服务节点变动(附zkUI使用)
  17. C#在获得客户端ip的时候,获得的ip地址为::1
  18. c语言switch例题考试成绩,使用C语言switch语句根据考试成绩等级输出百分制的分数段,规定如下: A:85~100 B:70~84 C:60~69 D:60...
  19. 杜甫写的有关风雨的古诗有哪些
  20. java安全架构____MD5加密原理和简介

热门文章

  1. 免费的编程中文书籍索引【收藏速度】
  2. 小家电行业遇冷,出海成为新选择?
  3. android项目uc浏览器,Android版UC浏览器7.4正式更新
  4. 头脑风暴-记一道有趣的问题
  5. 敖包相会:CECS三工作组联欢贺新年
  6. python全1向量_python – Numpy – 总结一个向量列表
  7. 最大子列和问题的分治算法
  8. 三维空间中的旋转矩阵
  9. 网摘:windows 3兄弟(xp、Vista、win7)
  10. 运营商三网,如何获取,抓取 有哪些窍门!