头文件的使用

来源:2-2 使用模板(泛型)编写算法

阿阳2017

2023-01-27

老师你好,这节课中,在头文件中直接实现自定义结构体的相关代码,对这种方式感觉到好奇。我已经参考了您的另外一个回答:
https://coding.imooc.com/learn/questiondetail/RAKpB2PJ8xWXbv0E.html
但是还有一个疑问就是:这个.h文件,在编译的时候也和.cpp文件一样编译么?课程中大致的理解是:“在Student.h中,把声明和实现一起写了出来,相当于一个开源项目,因为.h是不对外隐藏的;.cpp文件经过编译后,对外界隐藏。”,好奇是,这个h文件也被编译成可执行文件了么?那.h和.cpp好像除了信息隐藏,也没啥其他区别了。

写回答

2回答

规划局局长

2023-01-30

.h文件是头文件,内含函数声明、宏定义、结构体定义等内容
   .c文件是程序文件,内含函数实现,变量定义等内容。而且是什么后缀也没有关系,只不过编译器会默认对某些后缀的文件采取某些动作。你可以强制编译器把任何后缀的文件都当作c文件来编。
  这样分开写成两个文件是一个良好的编程风格。

1
0

liuyubobobo

2023-01-31

这个.h文件,在编译的时候也和.cpp文件一样编译么?

这其实是一个很“基础”的 C++ 问题,但是我很理解很多经常使用 C++ 的程序员都不很理解 C++的编译机制(其实包括其他语言的编译机制),尤其是国内很多教育相对忽视这一点。


简单回答就是,h 文件是不参与编译的,h 文件参与的是预处理。所以 #include 这类以 # 开头的指令叫做预处理指令。C++ 中的预处理指令可以参考这里:https://cplusplus.com/doc/tutorial/preprocessor/


#include 是最典型的预处理指令,预处理器处理 #include 的方式也非常简单,就是直接把 #include 对应的文件(通常是 .h 文件)的所有内容,直接复制粘贴到 cpp 文件中。最终编译器只针对 cpp 文件做编译工作。(compile)


==========


h 和 cpp 分离,除了对外界做隐藏之外,从软件工程的角度,更重要的是信息的分离,即接口和具体实现做分离。所以你可以不用知道 vector 是怎么实现的,只要 #include <vector>,然后直接用 vector 就好了。


你说的“开源“,是我选择将具体逻辑程序放到 h 中的最不重要的原因,而最重要的原因是,C++ 的模板类“原生不支持这种信息分离(实践一下试试看?我在你引用的问答里也给出了一个关于这个问题的讨论链接。)


从业界的角度,把具体实现放在 h 中也并不是不常用的手段。随便放一个例子。比如微软的 C++ STL 的开源实现,其整个 vector 类就是完整是现在 vector 的头文件中的:https://github.com/microsoft/STL/blob/main/stl/inc/vector


这背后还有一个重要的原因,把类实现放在 h 文件中,是一种隐式的声明内联(inline)的方式。深入下去涉及太多 C++ 的内容了。有兴趣你可以查询学习一下诸如这种问题的讨论:https://stackoverflow.com/questions/14517546/how-can-a-c-header-file-include-implementation 


(但如果你是以 C++ 作为主语言,尤其是工作用的话,还是建议完整学习 C++ 的知识。C++ 的知识非常庞大,说实话,是远高于“面试常用算法”这个范畴的。这里的 C++ 书单可以参考:https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list  )


继续加油!:)

1
1
阿阳2017
感谢老师的耐心回复,让我了解到cpp背后的一些知识。最近几年工作主要是前端开发,但是前些年一直断断续续学cpp。前端工程师最好还是掌握一门编译型语言,一直喜欢cpp,前几年也看过c++ primer。但是总感觉,语言的学习,和数据结构算法的实现,是割裂的。语言背后的知识也难以串起来。 以前买的这门课,让我觉得终于把语言知识和算法知识结合起来了,打通了关节。波波老师的课程以cpp讲解的只有两门,这门课是难得的宝藏课程。如果再出cpp相关的课程,必买。
2023-02-04
共1条回复

算法与数据结构(C++版) 面试/评级的算法复习技能包

课程专为:短时间内应对面试、升职测评等艰巨任务打造

11187 学习 · 1614 问题

查看课程