Day7 Makefile、gdb、小项目练习
一、分文件
main.c
#include "func.h"
int main(int argc, const char *argv[])
{
func();
printf("a + b = %d\n",add(100,200));
return 0;
}
func.c
#include "func.h"
void func()
{
printf("hello world!\n");
}
int add(int x,int y)
{
return x + y;
}
func.h
#ifndef /#define / #endif : 防止头文件被重复引用。
#ifndef _FUNC_H_ //如果没有func.h文件,#define_FUNC_H_文件。如果有,结束定义。
#define _FUNC_H_ //定义func.h文件
#include <stdio.h>
void func();
int add(int x,int y);
#endif
二、makefile
2.1makfile编译规则
Make工程管理器是完全根据Makefile文件中的编译规则命令进行工作的,Makefile文件由以下三项基本
内容组成:
(1) 需要生成的目标文件(Target file)
(2) 生成目标文件所需要的依赖文件(dependency)
(3) 生成目标文件的编译规则命令行(command)
target file:dependency file
command
这三项内容按照如下格式进行组织:
其中,makefile规则在书写command命令前必须加一个键(四个空格,即一个Tab)。
2.2Make工程管理器编译Test程序的过程
(1) Make工程管理器首先会在当前目录下读取Makefile文件
(2) 查找Makefile文件中的第一个目标文件(在本例中为test),该文件也是Make工程管理器本次编译任
务的最终目标。
(3) 把目标文件test的依赖文件当作目标文件进行依赖规则检查。这是一个递归的检查过程,在本例中就
是依次把a.o和b.o作为目标文件来检查各自的依赖规则。Make会根据以下三种情况进行处理。
① 如果当前目录下没有或缺少依赖文件,则执行其规则命令生成依赖文件(假如缺少a.o,则执行命
令”cc -c a.c“生成a.o)。
② 如果存在依赖文件,则把其作为目标文件来检查依赖规则(假如 a.c比a.o新,则执行命令”cc -c
a.c“更新a.o)
③ 如果目标文件比所有依赖文件都新,则不做处理。
(4) 递归执行第三步之后,就会得到目标文件test所有最新的依赖文件了,接着Make会根据以下三种情
况进行处理:
① 如果目标文件test不存在(比如第一次编译),则执行规则命令生成test
② 如果目标文件test存在,但存在比test要新的依赖文件,则执行规则命令更新test。
③ 目标文件test存在,且比所有依赖文件新,则不做处理。
2.3变量
在Makefile文件中,存在大量的文件名,而且这些文件名都是重复出现的。
所以在源文件比较多的情况下,很容易发生遗漏或写错文件名。而且一旦源文件的名称发生了变化,还容易造成与其它文件名不一致的错误。
于是,Makefile提供了变量名来代替文件名。
变量的使用方式:
$ (变量名) 或 ${变量名}
例如:
obj = a.o b.o
test : $(obj)
cc -o test $(obj)
a.o:a.c b.h
cc -c a.c
b.o:b.c
cc -c b.c
2.4变量定义的方式
(一)通过 ”=“来实现。
例如:
a1 = $(s2);
a2 = $(s3);
a3 = a.o
这种方式下变量a1的值是a.o,也就是说前面的变量可以通过后面的变量来定义。但使用这种方式定义
变量时,要防止出现死循环情况。
(二)通过 ”:=“来实现。
a1:= a.o
a2:= $(a1) b.o
这种方式下变量a1的值是a.o,变量a2的值是a.o b.o。
例如:
a1:= $(a2)
b.o a2:= a.o
这张方式下变量a1的值是b.o,而不是”a.o b.o“,也就是说前面的变量不能通过后面的变量来定义。
(三)通过 ”+=“来实现。
例如:
a1 = a.o;
a1 += b.o;
这种方式下变量a1的值是”a.o b.o“。也就是说”+=“可以实现给变量追加值。
等同于如下示例:
a1 = a.o;
a1:=$(a1) b.o
可以看出,Makefile的”+=“和c语言中的"+="是十分相似的。
(四)通过 "?="来实现。
例如:
a1 := a.o
a1 ?= b.o
这种方式下变量a1的值是a.o,而不是b.o,也就是说,如果变量a1已经在前面定义过了,那么后面的定
义就无效了。
三、gdb
gdb(代码调试的工具)的使用
编译:
gcc -g ***.c -o ***
【注】-g : 添加调试的信息
运行:
gdb ./可执行文件
运行之后:
(gdb) 输入gdb命令
查看文件源代码(list 简写为l)
(gdb) l 显示源代码,默认向后显示的10行
(gdb) l num 围绕num显示10行
(gdb) l - 向前显示num行
(gdb) l start,end 显示从start开始到end结束的行
设置断点(break 简写为b)
(gdb) b 行号
(gdb) b 函数名
disable + 断点的编号 禁用某一个断点
enable + 断点的编号 使能某一个断点
delete + 断点的编号 删除一个断点
查看断点的设置信息(info)
(gdb) info b
运行代码 (run 简写为r)
(gdb) r
查看变量的值(print 简写p)
(gdb) p i
恢复程序的运行(continue 简写为c)
(gdb) c
单步执行 (next 简写为n)
(gdb) n 单步运行之前,必须先执行run
查看帮助信息 (help 简写为h)
(gdb) h 命令
如果在(gdb)后边什么也不输入,直接回车,
默认执行上一条输入的指令
退出调试状态(quit 简写为q)
(gdb) q
四、通讯录
要求:
1.通过makefile管理代码
2.各个子功能:
a:添加用户(连续添加)
b:查看用户(按照姓名的首字母排序)
c:搜索用户(两种方式:id,用户名)
d:删除用户信息
e:修改用户信息
3.自己封装字符串处理函数
4. 年后验收