一、makefile
Makefile :用来管理代码的编译和链接
make工具解释
名称:Makefile、makefile(只有两种形式,首字母大写或小写)
Makefile的语法:
gcc main.c fun.c -o a.out -I$(INC) -L$(LIB)
目标文件:a.out
依赖文件:main.c fun.c
(注:$(OBJ) : $(SRC))
-I : 指定头文件所在位置
-L:指定使用到的库所在的位置
语法规则:
目标文件:依赖文件
编译方法
Makefile中的变量(没有确切的数据类型):
1. 自定义变量
定义:
变量名=值
引用:
$(变量名)
OBJ=a.out
$(OBJ) ----->a.out
2. 系统变量
$^: 所有依赖
$<:第一个依赖
$@:生成的目标
时间戳:在编译代码时,只编译修改后的源文件,其他没有修改的,只进行链接即可。
#a.out:main.c link.c
# gcc main.c link.c -o a.out
#自定义变量
#需要生成的目标
OBJ=a.out
#生成目标依赖的二进制文件
SRC=main.o
SRC+=link.o
#编译器
CC=gcc
#头文件所在位置
INC=../include
#库所在位置
LIB=../lib
#生成目标文件的编译规则
$(OBJ):$(SRC)
$(CC) $^ -o $@ -I$(INC) -L$(LIB)
#生成二进制文件的编译规则
%.o:%.c
$(CC) -c $^ -o $@ -I$(INC) -L$(LIB)
#main.o:main.c
# $(CC) -c $^ -o $@
#link.o:link.c
# $(CC) -c $^ -o $@
#伪指令:make clean执行该指令:删除目标文件和一些中间文件
clean:
rm $(OBJ) *.o
二、gcc编译的四个步骤
预处理:处理和#相关的指令
gcc -E main.c -o main.i
编译:将源程序转换成汇编指令
gcc -S main.i -o main.s
汇编:将汇编指令生成二进制指令
gcc -c main.s -o main.o
链接:处理多文件及函数的链接关系
gcc main.o -o app
三、双向链表
(1)创建双向链表
①在头文件(.h)中声明
#ifndef __DOULINK_H__
#define __DOULINK_H__
//双向链表存储的数据类型
typedef struct stu
{
int id;
char name[32];
int score;
}Data_type_t;
/*双向链表的结点类型*/
typedef struct dounode
{
Data_type_t data;
struct dounode *ppre; //指向前驱结点的指针
struct dounode *pnext; //指向后继结点的指针
}DNode_t;
/*双向链表对象类型*/
typedef struct doulink
{
DNode_t *phead; //双向链表头结点地址
int clen; //双向链表结点个数
}DLink_t;
②在编写文件(.c)中编写创建双向链表函数
DLink_t *create_doulink()
{
DLink_t *dplink = malloc(sizeof(DLink_t));
if(dplink == NULL)
{
printf("error\n");
return NULL;
}
dplink -> phead = NULL;
dplink -> clen = 0;
return dplink;
(2)判断链表是否为空
int is_empty_doulink(DLink_t *dplink)
{
return NULL == dplink -> phead;
}
(3)遍历双向链表(正向遍历,逆向遍历)
void printfDouLink(DLink_t *dplink, int dir)
{
DNode_t *ptmp = NULL;
if(dplink->phead == NULL)
{
return ;
}
ptmp = dplink -> phead;
if(dir)
{
while(ptmp != NULL)
{
printf("%d ,%s , %d\n",ptmp -> data.id,ptmp ->data.name,ptmp ->data.score);
ptmp = ptmp -> pnext;
}
puts("");
}
else
{
while(ptmp -> pnext != NULL)
{
ptmp = ptmp -> pnext;
}
while(ptmp != NULL)
{
printf("%d ,%s , %d\n",ptmp -> data.id,ptmp ->data.name,ptmp ->data.score);
ptmp = ptmp -> ppre;
}
}
}
(4)插入数据
①头插
int insert_doulink_head(DLink_t *dplink,Data_type_t data)
{
DNode_t *pnode = malloc(sizeof(DNode_t));
if(pnode == NULL)
{
printf("error\n");
return -1;
}
pnode -> data = data;
pnode -> pnext = NULL;
pnode -> ppre = NULL;
if(is_empty_doulink(dplink))
{
dplink -> phead = pnode;
}
else
{
pnode -> pnext = dplink -> phead;
dplink -> phead -> ppre = pnode;
dplink -> phead = pnode;
}
dplink -> clen++;
return 0;
}
②尾插
int insert_doulink_tail(DLink_t *dplink, Data_type_t data)
{
DNode_t *ptmp = dplink -> phead;
while(ptmp -> pnext != NULL)
{
ptmp = ptmp -> pnext;
}
DNode_t *pnode = malloc(sizeof(DNode_t));
if(pnode == NULL)
{
printf("error\n");
return -2;
}
pnode -> data = data;
pnode -> pnext = NULL;
pnode -> ppre = NULL;
if(is_empty_doulink(dplink))
{
insert_doulink_head(dplink,data);
}
ptmp -> pnext = pnode;
pnode -> ppre = ptmp;
dplink -> clen++;
return 0;
}
(5)
①头删
int delate_doulink_head(DLink_t *dplink)
{
if(dplink -> phead == NULL)
{
return -1;
}
DNode_t *ptmp = NULL;
if(dplink -> clen == 1)
{
ptmp = dplink -> phead;
dplink -> phead = NULL;
free(ptmp);
ptmp = NULL;
}
ptmp = dplink -> phead;
DNode_t *pnode = ptmp -> pnext;
dplink -> phead = pnode;
pnode -> ppre = NULL;
free(ptmp);
ptmp = NULL;
dplink -> clen--;
return 0;
}
②尾删
int delate_doulink_tail(DLink_t *dplink)
{
if(dplink -> phead == NULL)
{
return -1;
}
if(dplink -> clen == 1)
{
delate_doulink_head(dplink);
}
DNode_t *ptmp = dplink -> phead;
while(ptmp -> pnext != NULL)
{
ptmp = ptmp -> pnext;
}
ptmp -> ppre -> pnext = NULL;
free(ptmp);
ptmp = NULL;
return 0;
}
(6)销毁链表
void destroy_doulink(DLink_t *dplink)
{
if(dplink -> phead == NULL)
{
return ;
}
DNode_t *ptmp = NULL;
ptmp = dplink -> phead;
DNode_t *pnode = NULL;
while(ptmp != NULL)
{
pnode = ptmp -> pnext;
free(ptmp);
ptmp = pnode;
}
free(dplink);
ptmp = NULL;
}
(7)
①通过名字找节点,返回其地址
DNode_t *find_doulink_name(DLink_t *dplink,char *name)
{
if(dplink == NULL || name == NULL)
{
return NULL;
}
DNode_t *ptmp = dplink -> phead;
while(ptmp != NULL)
{
if(strcmp(ptmp->data.name , name) == 0)
{
return ptmp;
}
ptmp = ptmp -> pnext;
}
return NULL;
}
②通过名字修改其分数
int findname_doulink_changeScore(DLink_t *dplink,char *name,int newscore)
{
if(dplink -> phead == NULL && name == NULL)
{
return 0;
}
DNode_t *ret = NULL;
ret = find_doulink_name(dplink,name);
ret ->data.score = newscore;
return newscore;
}
(8)删除某个指定节点
int delnode_doulink_appoint(DLink_t *dplink,int k)
{
if(dplink -> phead ==NULL)
{
return 0;
}
if(dplink -> clen == 1)
{
delate_doulink_head;
}
DNode_t *ptmp = dplink -> phead;
int i;
for(i = 1;i <= k - 1;++i)
{
ptmp = ptmp -> pnext;
}
ptmp->ppre->pnext = ptmp->pnext;
ptmp->pnext->ppre = ptmp->ppre;
free(ptmp);
ptmp = NULL;
return 1;
}