我们在vs编译器中写的代码按下ctrl f5就可以直接运行起来,并且会将运行的结果显示到显示器上,这里看上去只有一个步骤但实际上这里会存在很多的细节,比如说生成结果在这里插入代码片
之前我们的代码会经过预处理,编译,汇编,链接的过程,不同的过程会对应不同的操作,那么接下来我们就会一个一个的介绍这些操作所对应的操作。
程序运行的第一步就是预处理,预处理的目的就是:将头文件展开,去掉注释,宏替换,删除条件编译,比如说我们创建一个临时文件test.c:
并且在这个文件里面输入一些内容:
1 #include 2 #define NUM_A 20 3 #define NUM_B 30 4 int main()5 {6 #ifdef add7 printf("相加的结果为:%d\n",NUM_A+NUM_B);//计算相加的结果8 #else9 printf("相减的结果为:%d\n",NUM_A-NUM_B);//计算相减的结果 10 #endif 11 return 0; 12 }
然后我们就退出并且保存这个文件:
到这里我们的准备工作就完成了。平时我们运行文件使用的指令是:gcc test.c
使用这个指令会自动的生成一个文件叫a.out,并且这个文件是一个可执行程序,我们运行一下这个程序就可以可以看到我们的屏幕上面出现了上面代码的运行的结果:
但是这里有个问题,使用这个指令我们看不到预处理的结果它直接变成了可执行程序,所以得在这个指令里面添加一个-E选项,这个选项的功能就是从重现在开始进行程序的翻译,将程序的预处理执行完后就停下来,所以使用这个选项我们就可以看到代码经过预处理之后的结果,那么这里的指令就是这样:gcc -E test.c
执行的结果如下:
我们可以看到这里出现很多乱七八糟的内容,那是因为这个指令将执行的结果全部都打印到屏幕上了,由于内容很多就显得很乱,不好查看,所以这里我们还可以在这个指令里面添加一个-o选项,这个选项的功能就是将指令的运行的结果放到一个文件里面,在-o的后面加上你要放的文件,如果这个文件不存在的话,这个指令会自动生成对应的文件,比如说我们将上面的指令修改成这样:gcc -E test.c -o test.i
当前目录下是没有test.i这个文件的,所以使用这个指令后我们会自动的生成test.i这个文件:
并且这个文件里面装的内容就是之前显示在屏幕上的内容:
我们可以使用vs指令将test.c文件显示在屏幕上进行对比:
我们使用shift+g将右边屏幕的光标移动到最后一行:
我们可以看到在test.i文件的最后出现了test.c文件中的大致内容,但是却略有不同这是test.i的相关内容:
这是test.c的全部内容:
仔细的观察一下我们可以看到有以下几点的不同:
那么这就是预编译所做的一些操作将头文件展开,去掉注释,宏替换,删除条件编译,那么这里大家要注意的一点就是在linux操作系统中文件的后缀是没有意义的,也就是说这里的后缀i对于操作系统来说是没有什么特殊意义的,但是这个后缀对我们使用者来说却有很多的意义,比如说我们看到了一个文件的后缀是i就可以想到这个文件是经过预处理后生成的文件,所以大家在执行这些操作生成文件的时候还是要将后缀写成对应的形式以免混淆别人,那么上面就是预处理要干的事情。
经历完预处理之后要执行的操作就是编译,编译要干的事情就是将c语言翻译成汇编语言,那么这里要执行的指令就是:gcc -S test.i -o test.s
那么这里-S选项的作用就是从现在开始进行程序的翻译,将汇编工作完成之后工作就停止,后面加了一个-o选项,所以这里会将执行完之后的结果放到test.s这个文件里面,执行完这个指令我们就可以看到这里自动的生成了一个test.s文件,在这个文件里面有我们好多我们看不懂的内容:
虽然下面的内容我们看不懂,但是可以知道的一件事就是这个test.o文件里面的内容是汇编语言:
我们知道计算器能够识别的语言是二进制语言,而test.o文件里面装的是汇编语言,所以这里的test.o文件无法被运行。
通过上面的讲解我们知道编译是将c语言翻译成汇编语言,那么这里的汇编要干的事情就是将生成的汇编语言翻译二进制语言,那么这里需要的指令就是:gcc -c test.s -o test.o
,-c选项的作用就是从现在开始进行翻译,将文件中的汇编语言翻译成二进制语言就停止,比如说下面的操作:
这里就自动生成一个test.o文件,我们打开这个文件就可以看到文件中的内容就变成了各种奇奇怪怪的符号:
这就是文件经过汇编之后的结果,那么这时肯定会有小伙伴想啊,既然这个文件的内容是二进制的话,我们是不是就可以运行这个文件呢?那么这里可以试一下看看能不能运行
结果很明显这个文件是无法运行的,原因也非常的简单因为我们上述的三个过程(预处理 编译 汇编)所干的事情是翻译的过程,也就是把你的代码进行修剪然后翻译成二进制文件,但是这里有个问题就是你的代码里面用了很多别人的函数,你没有在这个文件里面实现这些函数,比如说printf函数,scanf函数,main函数等等,这些函数你都没有实现,虽然你包含了头文件stdio.h,但是这个文件里面只有这些函数的声明,没有这些实现,所以将我们的代码翻译成二进制文件还是无法满足运行的需求,所以这里我们还得进行下一步链接。
链接干的事情就是把我们自己写的代码代码和c标准库的代码合并起来,这个标准库里面装的就是各种c语言函数的具体实现等等,所以当二进制文件经过链接后,里面使用的函数就有了具体的实现,就可以正常的被执行了,那么这里的用的之指令就是:gcc test.o
这里我们不使用-o选项的话,这里就会自动生成一个名为a.out的可执行程序,当然这里我们也可以人为的生成一个可执行程序,那么这里就得加上一个-o选项,那么这里的指令就是:gcc test.o -o mytest
当生成完可执行程序之后就可以运行以下这里的可执行文件:
那么上述就是这篇文章的全部内容希望大家可以理解谢谢。