Linux下程序的编写
C — gcc
C++ — g++
如果没有g++,可以使用下面的命令安装g++
gcc只能编译C语言,g++对于C语言、C++都可以编译
sudo yum install -y gcc-c++
程序(文本) -> 机器语言(二进制)
为什么计算机只认识二进制?组成计算机的各种组件,只认识二进制(磁盘(正负两极)……)
gcc和g++的只能相同,下面以gcc来讲
1、预处理:宏替换;头文件展开;去注释;条件编译
2、编译:将C语言编译成汇编语言
3、汇编:将汇编语言翻译成可重定位二进制文件(不能执行)
4、链接
-o 指定可执行程序的名称
-E 只预处理
从现在开始就进行程序的翻译,到预处理就停下来
顶一个DEBUG宏的话,就是保留ifdef那个了
此时还是C语言(你能看懂就是C语言)
-S 到编译
-S:从现在开始进行程序的翻译,当我们编译完成之后就停下来
-c 到汇编
-c:(c是小写!!!)从现在开始进行程序的翻译,当我们汇编完成之后就停下来
你在编译谁的代码??你只编译了自己的代码!
(1)我的代码中需要的printf在哪里呢??
在C标准库库中!
(2)我代码中使用的printf,如何和目标printf的实现产生管理(链接)
不用任何选项 链接-将我的代码和库中的代码链接起来
函数库
头文件:给我们提供可以使用的方法,所有的开发环境,具有语法提示,本质上是通过头文件帮我们搜索的
库文件:给我们提供可以使用方法的实现,以供链接,形成我们自己的可执行程序
静态库 -> 静态链接
Linux(.so) windows( .dll )
学校比较松,可以自己带电脑去学校
将用到的库中的代码都拷贝到可执行程序中
优点:不依赖任何库,程序可以独立的去执行
缺点:浪费资源
动态库 -> 动态链接
Linux( .a ) windows( .lib )
学校里比较严,不让带电脑,玩游戏需要去学校外面的电竞馆玩
优点:大家共享一个库,可以节省资源
缺点:一旦库缺失,会导致几乎所有的程序失效
默认可执行程序就是动态连接的
将可执行程序变成静态链接—加选项 -static
安装C的静态库
安装C++的静态库
gdb
Linux下默认形成的可执行程序是release版本的,无法进行调试
vs编译器下形成的可执行程序默认是debug版本的
-g选项就是将发布版本改成debug版本
debug的可执行程序自带一些调剂信息,而release没有(它们两个体积不一样)
l 显示代码(list)
b 打断点(breakpoint)
info b 查看打的断点
r 运行程序(run)、p 打印(print)
看变量的地址
s 逐语句执行(step)
n 逐过程(next)
d 断点编号 — 去断点
display 常显示变量的值 undisplay取消常显示
就像vs下的监视窗口
until 行数 — 跳转
当进入一个循环进行调试但发现这个循环没有问题,想跳出这个循环until
c 从一个断点运行到另一个断点(continue)
finish 执行完一个函数就停下来
makefile、make
makefile是在当前路径下的普通文件
make是一条命令
项目结构:
1、多个文件.h .c .cpp先编译哪一个程序?
2、链接需要哪些库?
库和头文件等在哪里找?
整个项目结构,该任何为何?
(在vs下是不需要我们考虑的因为是个集成环境,但在Linux下就需要我们考虑)
1、创建makefile文件(makefile/Makefile)
2、在makefile文件里面定义
(1)构建项目(make):依赖关系 test2->test2.c 、依赖方法 gcc test2.c -o test2
依赖方法前面必须 tab 键开头
(2)清理项目(make clean):没有依赖对象,是个伪目标
.PHONY可以看成是makefile中的一个关键字
.PHONY:伪目标 (总是被执行的)
总是被执行的意思:make 只能被执行一次,而make clean可以总是被执行。make会去看可执行程序和源文件的时间进行对比,若可执行程序时间更新则执行,否则不执行;而make clean则是忽略对比时间
为什么make是执行形成可执行文件而不是clean
make默认是总执行第一个
问题:那对于系统是怎么知道mytest是最新的了?
依照的文件的三个时间里面的modify
多个文件的makefile
1、不用makefile,而是使用gcc
这里gcc中形成可执行文件mytest依赖main.c test.c而没有头文件,是因为头文件在预处理阶段就展开了。
而头文件的查找方式其中有一种就是系统默认查找,这个要求:头文件要么在user/include里面、或者头文件在当前路径里面
2、使用makefile
make本来是只执行第一个的,但是此时在这里的第一个里面main.o和test.o没有找到是什么东西,就会继续向下执行