网站首页 > 技术文章 正文
今天用gcc编译器为大家演示一下c语言的编译过程
首先,我们将贴上我们朴实无华的源代码
1. 预编译过程
由.c --生成–> .o文件
通过 gcc -E main.c -o main.i 执行c语言的预编译过程,生成main.o文件
让我们怀着敬畏的心情瞧一瞧生成的main.o文件是啥样子
(因为篇幅原因,上面截图只展示原文件的几十分之一的代码)
可以发现最下面是我们的源代码部分,也就是main函数,那么,main函数上面的几千行代码都是什么东西呢?
其实啊,那是我们的#include <stdio.h>, 即是我们定义的宏展开的样子
千万别小看这个文件,它可是可以直接运行的
如果有神探的话,可以发现,我上面那个main函数是有语法错误的
我的main函数是这样的
int int mian(){
printf(".....");
return 0
}
1234
聪明的你们可以得出一个什么结论呢?
在预编译过程中是不会进行语法检查的,只会单纯的将我们定义的宏进行展开
编译
由.i文件生成.s汇编文件
gcc -s main.i -o main.s
这一步我赶紧偷偷将语法改正过来,因为有了语法检查喽(其实也是必然的,因为有语法错误怎么能编译为正确的汇编代码呢)
这个汇编文件包括我们下一步生成的目标文件是不可以直接运行的,因为它里面的函数调用等等也就是符号引用,并不知道此时他的真正的文件地址在哪里
生成目标文件
gcc -c main.s -o main.o
我们采用file命令查看一下这个目标文件
发现这个文件是Mach-O类型的,什么是Mach-O呢?
虽然macos拥有着unix上的很多特性,但是并没有采用unix上可执行文件elf(excutable link format)格式, 它采用了Mach-O作为它的可执行文件的格式, 哦,所以说,它其实就是一个mac平台上的可执行文件, 类似于unix的elf和win的PE
但是呢,它还没有进行链接,例如我们main函数中引用的printf的真正内存地址它还是没有的,所以,并不是一个真正意义上的可执行文件
生成可执行文件
激动。。。终于到了最后一步了
gcc -v main.o -o main 生成我们的可执行文件
我们双击一下这个文件,就可以发现这个文件可以正常运行了,是不是非常四高一呢?
猜你喜欢
- 2024-09-12 c++ printf 到 std::cout(c++怎么用printf输出整数)
- 2024-09-12 C 语言未初始化的局部变量是多少?
- 2024-09-12 大话C语言:函数(c语言函数视频讲解)
- 2024-09-12 每日一题||C语言刷题(c语言刷题网)
- 2024-09-12 大话C语言:逗号运算符及运算法优先级
- 2024-09-12 C语言学习篇(14)-----sizeof运算符
- 2024-09-12 C语言 include的用法(c语言include的用法与搭配)
- 2024-09-12 C语言的位运算基本操作演示(c语言位运算的运算规则)
- 2024-09-12 编写一个C程序,输入a,b,c三个值,输出其中最大值
- 2024-09-12 C语言如何实现大数相加(c语言大数相加思路)
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)