vi编辑器makefile的使用以及双向链表

发布于:2025-08-06 ⋅ 阅读:(13) ⋅ 点赞:(0)

一、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;
}


网站公告

今日签到

点亮在社区的每一天
去签到