数据结构(三)双向链表

一、什么是 make 工具?

make 是一个自动化构建工具,主要用于管理 C/C++ 项目的编译和链接过程。它通过读取 Makefile 文件中定义的规则,自动判断哪些文件被修改,并仅重新编译这些部分,从而大幅提高构建效率。


二、什么是 Makefile?

Makefilemake 工具的配置文件,它以纯文本形式存在,主要用于描述:

  • 构建目标(如:最终生成的可执行文件)

  • 依赖关系(如:源代码、头文件)

  • 构建命令(如:gcc 编译命令)

通过 Makefile,我们可以实现对大型项目的自动化编译管理。


三、Makefile 的基本语法

1. 基本格式

目标文件: 依赖文件列表 命令(以Tab键开头)

注意:命令必须以 Tab 缩进,否则 make 会报错。

示例:

a.out: main.c fun.c

    gcc main.c fun.c -o a.out -I$(INC) -L$(LIB)

  • 目标文件:a.out(最终生成的可执行文件)

  • 依赖文件:main.c、fun.c

  • 命令:gcc 编译命令,带有头文件和库路径参数


四、常用编译参数说明

  • -I$(INC):指定头文件目录(如 include/

  • -L$(LIB):指定库文件目录(如 lib/

  • -o:指定输出文件名称


五、Makefile 中的变量使用

1. 自定义变量

CC = gcc

TARGET = app

SRC = main.c fun.c

INC = ./include

LIB = ./lib

引用变量方式:$(变量名

$(TARGET): $(SRC)

    $(CC) $(SRC) -o $(TARGET) -I$(INC) -L$(LIB)

2. 系统自动变量

  • $@:表示当前规则的目标文件

  • $^:所有依赖文件(去重)

  • $<:第一个依赖文件

示例:

app: main.c fun.c tool.c gcc $^ -o $@

等价于:

gcc main.c fun.c tool.c -o app


六、make 的时间戳机制

make 会对比文件的时间戳来判断是否需要重新编译:

  • 若依赖文件比目标文件更新 → 执行构建命令

  • 否则跳过(显示 make: 'xxx' is up to date.

这种机制确保了编译效率,尤其适合大型项目。


七、GCC 编译的四个阶段

  1. 预处理(Preprocessing)
    处理 #include#define 等预处理指令,生成 .i 文件:

    gcc -E main.c -o main.i

  2. 编译(Compilation)
    .i 转为汇编 .s 文件:

    gcc -S main.i -o main.s

  3. 汇编(Assembly)
    .s 文件生成 .o 目标文件:

    gcc -c main.s -o main.o

  4. 链接(Linking)
    将多个 .o 文件和库链接为可执行程序:

    gcc main.o fun.o -o app


八、Makefile 示例(推荐写法)

# 定义变量  
CC = gcc  
CFLAGS = -I./include -Wall  # 编译选项:指定头文件目录 + 显示警告  
LDFLAGS = -L./lib -lm       # 链接选项:指定库目录 + 链接数学库  
TARGET = app  
SRCS = main.c fun.c  
OBJS = $(SRCS:.c=.o)        # 将 .c 文件转换为 .o 文件(如 main.c → main.o)  # 默认目标(第一个目标为默认)  
all: $(TARGET)  # 生成可执行文件  
$(TARGET): $(OBJS)  $(CC) $(OBJS) -o $@ $(LDFLAGS)  # 生成目标文件(.o)  
%.o: %.c                    # 模式规则:所有 .o 依赖对应的 .c  $(CC) -c $< -o $@ $(CFLAGS)  # 清理编译产物  
clean:  rm -f $(OBJS) $(TARGET)  

使用方法

  • 编译项目:make(默认执行 all 目标)
  • 清理文件:make clean
  • 重新编译:make clean && make

九、Makefile 使用方法

操作命令
编译项目make(默认执行 all)
清理项目make clean
重新编译make clean && make

十、双线链表基础语法

头文件

#ifndef _SIZEOF_DOUBLE_
#define _SIZEOF_DOUBLE_typedef struct stu
{int id;char name[32];int score;
}Data_type;typedef struct dounode
{Data_type data;struct dounode *ppre;struct dounode *pnext;
}DNode;typedef struct doulink
{DNode *phead;int clen;
}Dlink;extern Dlink *creatDoulink();
extern int IsEmptyDouLink(Dlink *pdlink);
extern int insertHeadDouLink(Dlink *pdlink, Data_type data);
extern void printDouLink(Dlink *pdlink, int dir);
extern int insertTailDouLink(Dlink *pdlink, Data_type data);
extern int deleteHeadDouLink(Dlink *pdlink);
extern int deleteTailDouLink(Dlink *pdlink);
extern int DestroyDouLink(Dlink *pdlink);extern DNode *findNameDouLink(Dlink *pdlink, char *s);extern int modifyScoreByName(Dlink *pdlink, char *s, int Score);
extern int deleteNodeByName(Dlink *pdlink, char *s);
#endif

定义函数

#include "doulink.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>Dlink *creatDoulink()
{Dlink *pdlink = malloc(sizeof(Dlink));if (NULL == pdlink){printf("malloc error\n");return NULL;}pdlink->phead = NULL;pdlink->clen = 0;return pdlink;
}int IsEmptyDouLink(Dlink *pdlink)
{return NULL == pdlink->phead;
}int insertHeadDouLink(Dlink *pdlink, Data_type data)
{DNode *pnode = malloc(sizeof(DNode));if(NULL == pnode){printf("malloc error\n");return -1;}pnode->data = data;pnode->pnext = NULL;pnode->ppre = NULL;if(IsEmptyDouLink(pdlink)){pdlink->phead = pnode;}else{pnode->pnext = pdlink->phead;pdlink->phead->ppre = pnode;pdlink->phead = pnode; }pdlink->clen++;return 0;
}void printDouLink(Dlink *pdlink, int dir)
{if(IsEmptyDouLink(pdlink)){return ;}DNode *temp = pdlink->phead;if(dir){while(temp){printf("%d %s %d\n", temp->data.id, temp->data.name, temp->data.score);temp = temp->pnext;}}else{temp = pdlink->phead;while(temp->pnext){temp = temp->pnext;   }while(temp){printf("%d %s %d\n", temp->data.id, temp->data.name, temp->data.score);temp = temp->ppre;}}return ;
}int insertTailDouLink(Dlink *pdlink, Data_type data)
{if(IsEmptyDouLink(pdlink)){insertHeadDouLink(pdlink, data);return 1;}else{DNode *pnode = malloc(sizeof(DNode));if(NULL == pnode){printf("malloc error\n");return -1;}pnode->data = data;pnode->ppre = NULL;pnode->pnext = NULL;DNode *temp = pdlink->phead;while (temp->pnext){temp = temp->pnext;}pnode->ppre = temp;temp->pnext = pnode;pdlink->clen++;return 1;}
}int deleteHeadDouLink(Dlink *pdlink)
{if(IsEmptyDouLink(pdlink)){return -1;}if(pdlink->phead->pnext == NULL){free(pdlink->phead);pdlink->phead = NULL;pdlink->clen--;return 1;}else{DNode *temp = pdlink->phead->pnext;temp->ppre = NULL;free(pdlink->phead);pdlink->phead = temp;pdlink->clen--;return 1;}}int deleteTailDouLink(Dlink *pdlink)
{if(IsEmptyDouLink(pdlink)){return -1;}if(pdlink->phead->pnext == NULL){free(pdlink->phead);pdlink->phead = NULL;pdlink->clen--;return 1;}else{DNode *temp = pdlink->phead;while(temp->pnext){temp = temp->pnext;}temp->ppre->pnext = NULL;free(temp);pdlink->clen--;return 1;}
}int DestroyDouLink(Dlink *pdlink)
{DNode *temp = pdlink->phead;while(temp){pdlink->phead = temp->pnext;free(temp);temp = pdlink->phead;}free(pdlink);return 1;
}DNode *findNameDouLink(Dlink *pdlink, char *s)
{if(IsEmptyDouLink(pdlink)){return NULL;}DNode *temp = pdlink->phead;while(temp){if(strcmp(temp->data.name, s) == 0){return temp;}temp = temp->pnext;}return NULL;
}int modifyScoreByName(Dlink *pdlink, char *s, int Score)
{DNode *temp = findNameDouLink(pdlink, s);if(temp == NULL){return -1;}temp->data.score = Score;return 1;
}int deleteNodeByName(Dlink *pdlink, char *s)
{if(IsEmptyDouLink(pdlink)){return -1;}DNode *temp = findNameDouLink(pdlink, s);if(temp->ppre == NULL){deleteHeadDouLink(pdlink);return 1;}if(temp->pnext == NULL){deleteTailDouLink(pdlink);return 1;}temp->pnext->ppre = temp->ppre;temp->ppre->pnext = temp->pnext;free(temp);pdlink->clen--;return 1;  
}

主函数

#include "doulink.h"
#include<stdio.h>int main(int argc, char const *argv[])
{Data_type stus[5] = {{1, "zhangsan", 99},{2, "lisi", 100},{3, "wangwu", 90},{4, "maliu", 56},{5, "tianqi", 66},};Dlink *pdlink = creatDoulink();if(NULL == pdlink){return -1;}insertHeadDouLink(pdlink, stus[0]);insertHeadDouLink(pdlink, stus[1]);insertHeadDouLink(pdlink, stus[2]);insertHeadDouLink(pdlink, stus[3]);//   insertHeadDouLink(pdlink, stus[4]);printDouLink(pdlink, 1);// printDouLink(pdlink, 0);//   deleteHeadDouLink(pdlink);
//   deleteTailDouLink(pdlink);printf("----------find----------\n");//    insertTailDouLink(pdlink, stus[4]);//    printDouLink(pdlink, 1);DNode * temp = findNameDouLink(pdlink, "lisi");printf("%d %s %d\n", temp->data.id, temp->data.name, temp->data.score);printf("----------modify----------\n");modifyScoreByName(pdlink, "wangwu", 999);printDouLink(pdlink, 1);printf("----------deletes design----------\n");deleteNodeByName(pdlink, "zhangsan");printDouLink(pdlink, 1);DestroyDouLink(pdlink);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/91955.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/91955.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在没有iCloud的情况下将联系人转移到新iPhone?

升级到新 iPhone 后&#xff0c;设置已完成&#xff0c;想在不使用 iCloud 的情况下将联系人从 iPhone 转移到 iPhone 吗&#xff1f;别担心。还有其他 5 种方法可以帮助您轻松地将联系人转移到新 iPhone。这样&#xff0c;您就无需再次重置新设备了。第 1 部分&#xff1a;如何…

SpringBoot3.x入门到精通系列:4.2 整合 Kafka 详解

SpringBoot 3.x 整合 Kafka 详解 &#x1f3af; Kafka简介 Apache Kafka是一个分布式流处理平台&#xff0c;主要用于构建实时数据管道和流应用程序。它具有高吞吐量、低延迟、可扩展性和容错性等特点。 核心概念 Producer: 生产者&#xff0c;发送消息到Kafka集群Consumer: 消…

Android audio之 AudioDeviceInventory

1. 类介绍 AudioDeviceInventory 是 Android 音频系统中的一个核心类,位于 frameworks/base/services/core/java/com/android/server/audio/ 路径下。它负责 管理所有音频设备的连接状态,包括设备的添加、移除、状态更新以及策略应用。 设备连接状态管理:记录所有已连接的音…

系统设计入门:成为更优秀的工程师

系统设计入门指南 动机 现在你可以学习如何设计大规模系统&#xff0c;为系统设计面试做准备。本指南包含的是一个有组织的资源集合&#xff0c;旨在帮助你了解如何构建可扩展的系统。 学习设计大规模系统 学习如何设计可扩展系统将帮助你成为更优秀的工程师。系统设计是一个…

Pandas数据分析工具基础

文章目录 0. 学习目标 1. Pandas的数据结构分析 1.1 Series - 序列 1.1.1 Series概念 1.1.2 Series类的构造方法 1.1.3 创建Series对象 1.1.3.1 基于列表创建Series对象 1.1.3.2 基于字典创建Series对象 1.1.4 获取Series对象的数据 1.1.5 Series对象的运算 1.1.6 增删Series对…

大模型——Qwen开源会写中文的生图模型Qwen-Image

Qwen开源会写中文的生图模型Qwen-Image 会写中文,这基本上是开源图片生成模型的独一份了。 这次开源的Qwen-Image 的最大卖点是“像素级文字生成”。它能直接在像素空间内完成排版:从小字注脚到整版海报均可清晰呈现,且同时支持英文字母与汉字。 以下图片均来自官网的生成…

大模型知识库(1)京东云 JoyAgent介绍

一、核心定位​ JoyAgent 是京东云推出的 ​首个 100% 开源的企业级多智能体平台&#xff0c;定位为“可插拔的智能发动机”&#xff0c;旨在通过开箱即用的产品级能力&#xff0c;降低企业部署智能体的门槛。其特点包括&#xff1a; ​完整开源​&#xff1a;前端&#xff0…

PowerShell 入门2: 使用帮助系统

PowerShell 入门 2&#xff1a;使用帮助系统 &#x1f3af; 一、认识 PowerShell 帮助系统 1. 使用 Get-Help 查看命令说明 Get-Help Get-Service或使用别名&#xff1a; gsv2. 更新帮助系统 Update-Help3. 搜索包含关键词的命令&#xff08;模糊搜索&#xff09; Help *log*&a…

hyper-v实战系列:显卡虚拟化(GPU分区)--windows篇详解

一般来说&#xff0c;windows系统中最常使用的虚拟机就3个&#xff1a;vmware workstation&#xff0c;virtualbox和微软系统自带的hyper-v。后面与前两者最大的区别就是能调用物理显卡的性能。 我在这篇博文会详述如何设置windows虚拟机的显卡虚拟化&#xff0c;并会随之…

WebGL应用实时云渲染改造后如何与网页端实现数据通信

WebGL是一种基于OpenGL ES 2.0的Web技术&#xff0c;属于BS架构&#xff0c;它允许在浏览器中渲染交互式3D和2D图形。 随着大场景高精度的开发要求深入&#xff0c;对于较高级的 WebGL 应用程序&#xff0c;需要性能更强的系统要求&#xff0c;如仍然维持低端硬件或浏览器&…

初始化列表,变量存储区域和友元变量

前言初始化列表是书写构造函数的一种方式&#xff0c;某些成员变量之只能通过初始化列表进行初始化。另外学习c不可避免地需要知道什么样的变量存储在什么区域当中如栈&#xff0c;堆&#xff0c;静态区&#xff0c;常量区初始化列表书写格式书写上&#xff0c;初始化列表&…

excel插入复选框 亲测有效

特别说明 1.开始位置是0 2.\u0052是勾选对号 3.\u25A1是不勾选 4.\u0052长度是1 5.\u25A1长度是1 6.汉字长度是1 7.起止位置不能超过索引位置(比如整体长度是6,截止位置最大填写5) 示例代码 package com.zycfc.xz.Util.excel;import org.apache.poi.hssf.usermodel.HSSFRichT…

Mac上优雅简单地使用Git:从入门到高效工作流

Mac上优雅简单地使用Git&#xff1a;从入门到高效工作流 本文将带你解锁在Mac上优雅使用Git的技巧&#xff0c;结合命令行与图形工具&#xff0c;让版本控制变得轻松高效&#xff01; 一、为什么Mac是Git的最佳搭档&#xff1f; 天生支持Unix命令&#xff1a;Git基于Linux开发…

一文了解SOA的纹波

什么是光谱纹波我们在SOA/RSOA/SLD的ASE&#xff08;放大的自发辐射&#xff09;光谱测试中&#xff0c;经常会观察到光谱中有周期性的变化&#xff0c;通常我们称之为纹波。在实际应用中&#xff0c;我们大多不希望这些纹波的存在。添加图片注释&#xff0c;不超过 140 字&…

ossutil 使用方法

目录 ossutil 使用方法 1. &#x1f4e4; 上传文件/文件夹到 OSS 上传单个文件&#xff1a; 上传整个文件夹&#xff08;递归&#xff09;&#xff1a; 2. &#x1f4e5; 从 OSS 下载文件/文件夹 下载单个文件&#xff1a; 下载整个文件夹&#xff1a; ossutil 使用方法…

从“多、老、旧”到“4i焕新”:品牌官方商城(小程序/官网/APP···)的范式跃迁与增长再想象

全新升级版本「佛罗伦萨小镇奥莱GO」商城正式上线&#xff01;会员福利加码 2025年&#xff0c;品牌官方商城应该如何定义&#xff1f;—— 还是一套“电商货架”&#xff1f; 在商派看来&#xff0c;现如今“品牌官方商城”则需要重新定义&#xff0c;结合不同品牌企业的业务…

WIN QT libsndfile库编译及使用

一、概述 libsndfile库是一个用 C 语言编写的开源库&#xff0c;用于读取和写入多种音频文件格式。 环境&#xff1a;QT5.9.9、cmakegui3.23.0、QT的编译器是minWG32 二、安装 1、下载libsndfile源码&#xff0c;连接&#xff1a;https://github.com/libsndfile/libsndfile…

Supergateway教程

Supergateway 是一款专为 MCP&#xff08;Model Context Protocol&#xff09;服务器设计的远程调试与集成工具&#xff0c;通过 SSE&#xff08;Server-Sent Events&#xff09;或 WebSocket&#xff08;WS&#xff09;协议实现基于 stdio 的服务器与客户端的高效通信。 Super…

203.移除链表元素 707.设计链表 206.反转链表

203.移除链表元素 Python链表节点定义&#xff1a; class ListNode:def __init__(self, val, nextNone):self.val valself.next next 性能分析 链表的特性和数组的特性进行一个对比&#xff0c;如图所示&#xff1a; 203. 移除链表元素 这道题就是给大家一个链表&#x…

人工智能之数学基础:利用全概率公式如何将复杂事件转为简单事件

本文重点 全概率公式是概率论中的核心工具,用于计算复杂事件的概率。其核心思想是将复杂事件分解为若干互斥且穷尽的简单事件,通过计算各简单事件的概率及其条件概率,最终求得目标事件的概率。 全概率公式 全概率公式就是将复杂事件简单化,定义如下: 如果随机事件A1,…