上一节我们讲了如何用VS2019新建一个“控制台应用程序”,这一节我们用同样的方式先创建一个“空项目”,然后在左侧项目的源文件中右键“添加”->“新建项”,新建一个“main.c”的文件,然后把下面的代码敲进去:
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
1. 头文件
所有程序员在编程写项目的时候,一般都不可能从第一行到最后一行全部是自己独立敲出来的,很多情况下我们都是把最核心的结构和算法自己编写,然后其他通用的功能模块去找系统公开的,或者网上已经开源的别人早已经写的很成熟的代码,拿过来稍微改动一下直接用。
C语言中“头文件”就是比较典型的“拿来用”的一个定义文件。我们把后缀为.h的文件叫做C语言的头文件,头文件大多用于存放已经写好的很成熟的可以直接用的功能代码,这个功能代码可以是别人写的,也可以是我们在安装VS的时候软件自动给我们提供的。
我们看上面代码的第一行 #include <stdio.h>
,inlcude 是包含的意思,stdio.h 就是一个VS安装时自动化安装到我们系统的一个头文件。我们按住Ctrl,然后把鼠标移动到这行代码上,变成链接状时点击鼠标左键,就自动打开了这个stdio.h文件。我们在这个头文件名上右键“打开所在的文件夹”,然后就能打开这个文件在你电脑的位置。我们看到这里面还有很多其他的头文件,都是VS自动给我安装好可以直接用的。这里面的名字我们不用都记住,因为日常用的就那么几个,即时遇到需要但不知道名字的,在网上查一下就能找到。
#include <stdio.h> 是一个固定的书写格式,#include 后面加空格再加一个 <文件名>,表示我的程序中用到了这个头文件中的某个功能,所以我在第一行就把这个头文件包含到我的代码中。在我们的代码中 printf 这个函数就是 stdio.h 中的一个功能,所以引入的是 stdio.h。如果我们代码中还使用了其他功能,我们需要在最前面把它所在的头文件include 进来,比如如果用到数学公式一类的功能,我们就把 math.h引入进来,用到时间一类的功能,就把 time.h 引入进来。一个功能都没用到,就全都不需要写。
这里有一点需要注意的是,我们之前说,网上别人写的代码我们也可以下下来直接用,那是不是也是 #include <xxx.h> 这样写呢?并不是这样。
在VS中除了编译器和链接器外,还有一个叫做“预处理器”的东西,这个东西要干活之一,就是在编译器编译程序之前,把所有的 #include 的文件包含进来。
注意,把 #include 的头文件包含到我们代码中,并不是编译器做的事情,而是预处理器干的事情。预处理器在包含这些头文件的时候,会有一个规则,他会把所有 <> 这个格式的头文件,在VS默认安装的头文件目录中查找,把 #include "xxx.h" 这种格式的头文件,先从你项目目录找,找到了就用你项目目录这个,如果找不到,再从VS默认安装的目录中查找。
举个例子,比如这里我们新建一个test.h的头文件,在里面简单写一个 int a = 1;
,然后我们想在mian.c中引用我们自己写的这个头文件,就可以在最前面 #include "test.h",如果你写成 #include <test.h>,就是告诉VS的预处理器,在VS默认安装的目录中查找 test.h 这个文件,编译的时候就会报错,提示我们 " 无法打开包括文件'test.h' ”,因为VS安装的那个头文件目录根本就没有这个文件。我们改成 #include "test.h",表示让VS预处理器先从我们项目目录找这个 test.h 文件,如果找不到再到VS默认安装的头文件目录中查找。项目目录中有这个文件吗?我们在项目名上右键选择“在文件资源管理器中打开文件夹”,我们发现有这个文件,所以编译的时候正确,说明我们引入对了。
如果我这里自己写的头文件名字不是test.h,而是stdio.h,那么当我 #include "stdio.h" 的时候,引入的是我们项目目录下的stdio.h,当我 #include <stdio.h> 就是指VS默认安装的头文件目录。但如果将我们自己写的这个 stdio.h 删除,而还是用 #include "stdio.h" 这种写法,会不会报错?当然不会,因为预处理器先查找你项目目录,找不到后又找了VS默认安装的头文件目录,那里面是有的。
如果你从网上下了一份C语言源代码学习的时候,看到头文件全是 #include "",那这些头文件是你目录下自己
写的呢,还是系统头文件目录里的呢?可能会一头雾水,看起来很费劲。所以,头文件这里,按照执行结果来说, #include <stdio.h> 和 #include "stdio.h" 都正确,但按照我们日常的习惯,VS安装目录下的就用<>
写,我们自己项目目录下的,就用""
写,这样你的代码更加严谨,质量更高。
2. 源文件
我们再来看以.c为后缀的文件,我们把它叫做源文件。源文件一般就用来存放我们自己编写的核心逻辑代码。一个.c的源文件可以包含任意多个.h的头文件,而一个.h文件,原则上不允许包含.c文件,但.h文件里面,可以包含其他.h文件。
放在最后彩蛋:其实.h文件和.c文件这种后缀的规定,是我们在日常编程时候大家所达成的一个共识,对于编译来说,他可能并不在乎。比如我们把.c和.h改成其他后缀,再编译一下试试,也能正确生成exe。但此时VS就不会识别我们编辑的语法什么的,很不方便。
VS在编译代码的时候,只会按照你这个文件用哪种方式去操作(可以在文件右键“属性”中查看),完全不在乎你文件的后缀是什么。
如果大家都只按机器执行结果来编程,那你可以写的天马行空,没人能看懂。但很多时候,你需要写的代码,都是需要和别人沟通交流,或者参考了别人的源码之后才能写出来的。所以,在最开始学编程的时候,一定要严格规范自己的编程习惯,这一点非常重要。
3. 生成exe文件的大小
这里有一个问题,如果我们 #include 很多头文件,说明我们代码用引入了很多其他代码,那我们生成的exe文件是不是会很大?其实不是这样,编译器在编译代码的时候,并不会把你写的所有代码都编译到生成的EXE文件中,编译器只会把你功能里用到的那部分代码编译到exe中,即使我们 #include 很多头文件,也不过是把用到的头文件中的某个功能编译到exe,所以最终生成的exe文件并会很大。