关于头文件和源文件的分别

关于头文件和源文件的分别

首先,我们可以将所有东西都放在一个.cpp文件内.

然后编译器就将这个.cpp编译成.obj,obj是什么东西?

就是编译单元了.一个程序,可以由一个编译单元组成,

也可以有多个编译单元组成. 如果你不想让你的源代码变得很难阅读的话,

就请使用多个编译单元吧.(一个函数不能放到两个编译单元里面,但两个以上

就可以分别放在一个单元,也就是cpp里面)

    那么就是一个.cpp对应一个.obj,然后将所有的obj链接起来(通过一个叫链接器的程序),

组成一个.exe,也就是程序了.

    如果一个.cpp要用到另一个.cpp定义的函数怎么办? 只需在这个.cpp种写上他的函数声明

就可以了.其余工作由链接器帮你完成,你可以随便调用该函数.

    链接器将所有的obj连接起来,但是如果碰巧有相同的函数或外部变量怎么办?他如何识别?

一般来说是不能允许在同一个程序中,出现两个一样的函数名或外部变量名.

    但是只得庆幸的是,c++可以通过一种叫做链接属性的关键字来限定,你这个函数是属于整个程序

公用的,还是只是在一个编译单元obj里面使用的.

    这些关键字就是extern static extern是外部链接的意思,也就是除了这个单元,外部的单元

也是能够访问这个函数的.static 是内部链接,自属于自己单元.

说了这么久,还没有说.h的作用呢?

    其实没有.h也能很好的工作,但是当你发现一个外部链接的函数或外部变量,需要许多份

声明,因为c++这种语言,在使用函数和变量的时候,必须将他声明,为何要声明?声明之后才

知道他的规格,才能更好的发现不和规格的部分.你别妄想一个编译单元,会自动从另一个

编译单元那里得到什么信息,知道你是如何定义这个函数的.

    所以说,只要使用到该函数的单元,就必须写一份声明在那个.cpp里面,这样是不是很麻烦,

而且,如果要修改,就必须一个一个修改.这真让人受不了.


.h
就是为了解决这个问题而诞生,他包含了这些公共的东西.然后所有需要使用该函数的.cpp,只需要

#include包含进去便可.以后需要修改,也只是修改一份内容.


请注意不要滥用.h,.h里面不要写代码,.h不是.cpp的仓库,什么都塞到里面.

如果在里面写代码,当其他.cpp包含他的时候,就会出现重复定义的情况,

比如将函数func(){printf};放到头文件a.h,里面还有一些a.cpp需要的声明等;

然后你发现b.cpp需要用到a.cpp里面的一个函数,就很高兴的将a.h包含进来.

注意,#include并不是什么申请指令,他就是将指定的文件的内容,原封不动的拷贝

进来.


这时候实际上a.cppb.cpp都有一个func()函数的定义.

如果这个函数是内部链接static的话,还好,浪费了一倍空间;

如果是extern,外部链接(这个是默认情况),那么根据在同一个程序内不可出现

同名函数的要求,连接器会毫不留情给你一个连接错误!

 

<think>好的,我现在要解答用户关于C/C++中头文件源文件的区别及使用方法的问题。首先,我需要回顾一下已有的知识,并结合提供的参考资料来整理出一个清晰的回答。 根据用户提供的引用[1]、[2]、[3],头文件(.h或.hpp)源文件(.cpp)在C++中扮演不同的角色。头文件主要用于声明类、函数、变量宏等,而源文件则包含这些声明的具体实现。引用中提到的include guard(#ifndef、#define、#endif)是为了防止头文件被重复包含,确保编译的正确性。此外,头文件中的声明可以让多个源文件共享接口,提高代码的模块化重用性。 我需要明确区两者的用途:头文件是接口的声明,源文件是实现。例如,类的方法在头文件中声明,在源文件中定义。这样在编译时,编译器只需要知道函数的声明就可以进行类型检查,而具体的实现则在链接阶段处理。 接下来要组织回答的结构。首先解释头文件源文件的定义,然后别说明它们的用途,接着比较两者的区别,最后给出使用方法,比如如何正确编写头文件源文件,以及如何包含头文件。可能还需要提到编译过程,因为头文件的包含直接影响编译单元的形成。 需要确保使用正确的中文术语,并引用提供的资料中的要点。例如,引用[2]提到头文件包含声明,源文件包含定义实现,引用[3]则强调了include guard的重要性。此外,示例代码可以帮助用户更好地理解如何实际操作。 在回答过程中,还要注意用户可能存在的疑问,比如为什么需要头文件源文件,重复包含的问题如何处理,以及实际项目中的最佳实践。同时,生成的相关问题需要围绕这些知识点展开,帮助用户进一步学习。 最后,检查是否符合系统级指令的要求:行内公式用$...$,独立公式用$$...$$,语法正确,使用中文,生成相关问题,并在引用处添加标识。确保回答结构清晰,点明确,示例代码正确,引用标注正确。</think>### C/C++头文件源文件的区别及使用方法 #### 一、核心区别 1. **内容差异** - **头文件(.h/.hpp)**:存放**声明**,包括函数原型、类定义、宏定义、类型别名、外部变量声明等。例如: ```cpp // example.h #ifndef EXAMPLE_H #define EXAMPLE_H int add(int a, int b); // 函数声明 #endif ``` - **源文件(.cpp)**:存放**定义与实现**,包括函数体、类方法实现、全局变量初始化等。例如: ```cpp // example.cpp #include "example.h" int add(int a, int b) { // 函数定义 return a + b; } ``` 2. **编译机制** - 头文件通过`#include`被**文本替换**到源文件中,形成编译单元[^1]。 - 源文件独立编译生成目标文件(.obj),最终由链接器合并。 #### 二、核心用途 | 类型 | 用途 | 示例场景 | |------------|----------------------------------------------------------------------|----------------------------| | **头文件** | 提供接口声明,实现代码复用模块化 | 声明库函数、定义数据结构 | | **源文件** | 实现具体功能,隐藏实现细节,减少编译依赖 | 编写算法逻辑、类方法实现 | #### 三、使用方法 1. **头文件编写规范** - 使用`#ifndef`-**`#define`**-`#endif`防止重复包含[^3]: ```cpp #ifndef MY_HEADER_H #define MY_HEADER_H // 声明内容 #endif ``` - 避免在头文件中定义变量(可能引发重复定义错误),用`extern`声明外部变量: ```cpp extern int global_var; // 声明 ``` 2. **源文件编写规范** - 包含关联的头文件: ```cpp #include "my_header.h" ``` - 实现头文件中声明的所有接口: ```cpp int global_var = 42; // 定义 ``` 3. **跨文件调用示例** ```cpp // math_utils.h #pragma once double sqrt(double x); // 声明 // math_utils.cpp #include "math_utils.h" #include <cmath> double sqrt(double x) { // 定义 return std::sqrt(x); } // main.cpp #include "math_utils.h" int main() { double result = sqrt(4.0); // 调用 return 0; } ``` #### 四、常见问题解答 **Q1: 为什么不能直接在头文件中写函数定义
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值