做装修的网站,企业建站个人建站源码,wordpress 生成封面,用c语言做网站一、文章来由 写项目的时候发现了这个问题#xff0c;又是一个比较底层的问题#xff0c;首先说明#xff0c;这篇文章只是我根据查阅的资料和做的实验提出的一个讨论#xff0c;并不一定就是正确答案。因为这个问题网上众说纷纭#xff0c;我很欢迎大家参与这个讨论… 一、文章来由 写项目的时候发现了这个问题又是一个比较底层的问题首先说明这篇文章只是我根据查阅的资料和做的实验提出的一个讨论并不一定就是正确答案。因为这个问题网上众说纷纭我很欢迎大家参与这个讨论一起搞懂这个问题~~~ 二、问题的提出 问题就是。。。 2.1 问题1主问题 头文件是否真正参与编译 先上一个网上的标准答案 .h的内容被插入到.c中作为.c的内容被编译。.h文件本身不直接参加编译。 据我理解这句话就是说明了头文件不直接参与编译是作为一个插入来理解。 也就是说 是要编译的只不过这些头文件是预编译的。每个源文件包涵的头文件都会被预编译包含到源文件中去。 这样就又牵出来三个子问题~~ 2.2 问题2 预编译是什么 网上的答案大致理解为类似复制粘贴的操作这样理解是有理由的因为 1头文件不一定是 .h 文件可以是任意类型 2头文件可以定义一些很奇怪的东西见下面的代码 // testheadcompile.h
1, 2, 3, 4, 5//main.cpp
#include iostream
using namespace std;int main()
{int a[] {#include testheadcompile.h};couta[1]endl;return 0;
} 分析 这段代码可以说是真的变态因为头文件写在了函数体内这么说的确就像是一个复制粘贴关键是可以跑出结果我在vs2012 release模式下结果如下 而且还被360误认为是木马。。。 于是我这样认为如果需要什么东西变量或者方法的时候就直接可以像利用 #define 一样用 #include 了而且#include有井号本身就是宏的写法~~ 但是发现把 include 像上面一样写在方法体内定义变量可以函数不行否则会报“本地函数定义是非法的”的错但如果 include 在开头就可以正常使用函数。这又是一个预处理的典型代表说明了在函数里面定义了函数~~~ 其实甚至可以写出这种鬼畜的代码 // testheadcompile.h
1, 2, 3, 4//main.cpp
#include iostream
using namespace std;int main()
{int a[] {#include testheadcompile.h,5};couta[4]endl;return 0;
} 答案是5 2.3 问题3 既然上面说是预编译或者说是单纯的复制那么那些没有实现的函数预编译编译链接的时候编译器怎么做的那些实现了在整个过程没有用到的函数呢 这个问题我是这样看的 所有的编译都是单独的没有实现的函数就没有单独实现的编译如果用到了找不到实现体就会报链接错误也就是vs里面常见的“fatal error LNKXXX: N 个无法解析的外部命令”。。。 而对于头文件的作用仅仅是为了在编译的时候告诉编译器这里如果用到一些其他文件的东西我实现了编译别报错 所以这么说实现了但在整个过程没有用到的函数是编译了的但没有被链接进最后的可执行文件。可能有不对的地方欢迎指正 2.4 问题4 既然说没有参与编译只是参与预编译但是可以在头文件里面定义函数又如何解释 首先我来回答一下这个问题个人感觉是参与编译的但是是头文件被包含到源文件进行编译也就是说编译器只会编译源文件不被包含的头文件是没有存在的意义的因为我故意把头文件写错然后这样报错。。。 刚刚测试发现了一个现象没有cpp文件vs也可以编译我怀疑在编译的时候默认将main函数所在的文件作为编译文件即使main函数写在头文件也可以正常执行。 而在Linux下面用编译器编译时需要指定编译的文件所以有没有后缀名是无关紧要的反正都是文本文件读取方式就是确定的所以Linux对于后缀名并不重要。