【Linux基础六】Linux开发工具—中(gcc和g++)
1.gcc和g++介绍
Linux系统不看分文件后缀,不代表linux下的各种程序不看
而gcc和g++就是看后缀的
gcc:C语言编译器,只能编译C语言
g++:C++编译器,C/C++都能编译
将 test.c 生成可执行程序:
gcc test.c
将 test.c 生成可执行程序并自定义程序名:
gcc test.c -o 程序名
使用C99标准编译:
gcc test。c -std=99
2.执行可执行程序
当我们编译好程序后,在当前目录里会生成一个文件
运行程序
./a.out
.
代表在当前目录下寻找可执行文件
3.程序翻译的四个阶段
按照顺序分别是:预处理、编译、汇编、链接
3.1预处理
在这个阶段一共要办四件事:
- 头文件展开
- 去掉注释
- 条件编译
- 宏替换
让我们使用代码单独看一下预处理阶段:(生成后缀为.i
文件)
gcc -E test.c -o test.i
查看tset.i文件:
vim test.i
代码部分展示:
可以看到在我们代码之前多了很多代码,这都是头文件的展开
头文件展开就是将头文件的内容拷贝到当前文件
在头文件中的空行是被去掉的注释
3.2编译
- 这个阶段是将C语言转变为汇编语言
让我们使用代码单独看一下编译阶段:(生成后缀为.s
文件)
gcc -S test.i -o test.s
查看汇编语言:
vim test.s
汇编语言在没有了解的情况下很难看懂
3.3汇编
- 这个阶段是将汇编代码转变为可重定位的二进制文件
让我们使用代码单独看一下汇编阶段:(生成后缀为.o
文件)
gcc -c test.s -o test.o
用vim查看是乱码,可以用指令od查看二进制文件
od test.o
3.4链接
- 大致流程:
.o
文件 + 系统库 = 可执行程序
具体解释请看接下来的动静态库
4.动静态库(库函数的命名和分类)
我们在C语言代码中写的
printf
并没有去实现它的功能,stdio.h
头文件中也只有printf
的说明
printf
的功能如何实现呢?一切都是因为库的存在
查看可执行程序依赖的第三方库:
ldd 可执行程序名
libc.so.6就是C语言程序依赖的库
在linux下:
.so
是动态库.a
是静态库
在windows下:
.ddl
是动态库.lib
是静态库
连接过程就是将
.o
文件与动静态库结合的过程
5.动静态库的区别
- 动态库是共享库,通过函数地址来关联程序
是C/C++或其他第三方提供的所有方法的集合,被所有程序以动态链接的方式关联起来 - 静态库是私有库,可以独立运行
是C/C++或其他第三方提供所有方法的集合,被所有程序以拷贝的方式将需要的代码拷贝至自己的可执行程序当中
编译代码时默认使用动态库
Linux下绝大部分库都是静态库
使用静态库编译:
gcc code.c -static
6.拓展
6.1 gcc的选项:
6.2计算机语言历程
- 用二进制写程序
- 为了方便,用二进制写出了汇编翻译器,发明了汇编语言
- 发展出了许多语言,例如用汇编语言写出了C语言翻译器,发明了C语言
- 用C语言写程序
6.3站在巨人的肩膀上
- 为什么不直接把C语言转换为二进制?
因为每次革新伴随着巨大的人力物力时间,既然汇编语言编写更加高效,又早已存在翻译成二进制的翻译器,所以没必要舍弃汇编语言