当前位置: 首页 > news >正文

华清远见25072班数据结构学习day1

重点内容:

Makefile:

        是一个工程管理文件

学Makefile的作用:

        完成对程序的高效编译、Makefile会将编译流程,拆成两步:

        1.生成二进制中间文件,.o          2.根据二进制中间文件生成可执行文件

Makefile对编译流程的优化:

        当多文件编译时,如果部分文件没有发生修改,重新生成可执行文件时无需重新编译没有修改过的文件

Makefile文件的书写和执行:

        make工具用于执行Makefile文件

        如果虚拟机中没有装Makefile文件,sudo apt-get install make

        测试虚拟机中是否由make工具:直接在终端输入make

make工具的使用:

  1. Makefile文件是make工具的默认读入文件
  2. 当makefile和Makefile同时存在时,make默认读makefile
  3. make -f 指定的文件名
  4. 在终端直接输入make,默认会读Makefile文件中的第一个目标
  5. make 目标名 ---->让make读取Makefile中指定的目标

Makefile文件的构成:

  1. 规则
  2. 变量
  3. 函数

Makefile中规则的构成:

        目标:依赖 <tab>指令(往往是由依赖生成目标的指令)

        一条规则中可以只有目标和依赖没有指令,只描述依赖关系

        一条规则中可以只执行指令只有目标,没有依赖

        一条规则中必须有一个目标

Makefile生成文件的依据:

        Makefile根据文件的时间错,来判断文件是否需要重新生成,如果依赖文件的时间戳比目标文件更新,那么说明目标文件需要重新生成

Makefile中的变量:

变量的赋值方式:

        =:递归赋值

         +=:追加赋值

        ?=:条件赋值

        := 立即赋值

变量的使用:

        变量名=变量的值

        使用变量的值$(变量名) $变量名

伪目标.PHONY:

        Makefile默认每条规则都是要生成文件,每个目标都是要生成的文件名

        伪目标的作用:无论是否存在和目标同名文件,都去执行目标下的规则

引入函数:

        Makefile所编译的文件和Makefile文件在同一个目录下

wildcard:

        功能:在当前路径下,根据所给的特征查找文件

        使用: $(wildcard 指定格式)

        例:$(wildcard *.c) ---->查找当前路径下所有的.c文件

patsubst:

        功能:用格式匹配的方式获取新的字符串

        使用: $(patsubst 源格式,新格式,要替换的字符串)

        例: $(patsubst %.c,%.o,1.c 2.c)

Makefile的最终版本(通用版本):

        EXE=fun #可执行文件

        CC=gcc #CC用来保存程序所需编译器名字

        Objs=$(patsubst %.c,%.o,$(wildcard *.c))

        CFlags=-c -o #编译参数

        all:$(EXE)

         $(EXE):$(Objs)

                $(CC) $^ -o $@

        %.o:%.c #引入通配符

                $(CC) $^ $(CFlags) $@

        .PHONY:clean

        clean: rm $(EXE) $(Objs)


数据结构:

逻辑结构:

  1. 线性结构:数据之间是一对一的关系
  2. 非线性结构:集合、树、图(数据之间没有逻辑关系/不是一对一的关系)

物理结构:

数据在计算机中实际的存储方式
  1. 顺序存储:内存连续(数组)
  2. 链式存储:内存不连续,用指针存储下一个数据的地址
  3. 散列存储:根据关键字为数据分配空间
  4. 索引存储:一本书的目录和内页

存储类型:

const:

        const修饰的变量,拥有常量的属性,不能在代码中更改

const和指针结合:

        const在谁前面就修饰谁,在*p前就修饰*p,在p前就修饰p

常量指针:

        const int *p = &a;

        指向常量的指针,*p不能更改

指针常量:

        int * const p = &a;

        是一个指针类型的常量,指针的指向不能更改

volatile:

        每次去内存中取数据的值(不去cache高速缓存器中取数据)

extern:

        外部文件中变量的声明

        extern int a; ----->不能写=,只是声明可能会使用到外部文件中的变量a

顺序表:

概念:

        是顺序存储的线性表

操作:

        顺序表的结构体

        申请顺序表的空间

        元素前移和后移的问题:

                循环前移:从前面开始移动

                循环后移:从后面开始移动


作业:

1.多文件编译,一般存在三个文件,但是课上的Makefile中只考虑了两个.c文件,并没有考虑到头文件(.h),如果现在只有.h发生过修改,怎么样让Makefile重新编译。

程序源码:

EXE=fun
CC=gcc
OBJES=$(patsubst %.c,%.o,$(wildcard *.c))
CFLAGS=-c -o

#一般默认第一个规则的目标为all
all:$(EXE)

#第一个规则
#fun目标依赖main.o test.o

$(EXE):$(OBJES) *.h
$(CC) $^ -o $@

#main.o依赖main.c
# 当目标为main.o,会默认执行下面的规则
# %等价main,展开结果---》main.o:main.c
# 当目标为test.o
# %等价test,会展开结果-->test.o:test.c

%.o:%.c 
$(CC) $(CFLAGS) $@ $^

.phony:clean

#删除所有.o文件以及 hello可执行文件
#  @当执行指令时不会在当前终端打印

clean:
@rm $(OBJES) $(EXE)

2.实现顺序表的头删、输出

顺序表的头删:

顺序表的打印输出:

程序源码:

                                                                (fun.c)

#include "head.h"
int empty_sqlist(list_p sqlist)
{
if(sqlist->len==0)
{
return 1;
}
else
{
return 0;
}
}
int full_sq(list_p sqlist)
{
//检测顺序表是否已满
if(sqlist->len==MAX)
{
return 1;
}
else
{
return 0;
}
}

list_p create_list()
{
list_p sqlist=(list_p)malloc(sizeof(list));
if(sqlist==NULL)
{
printf("申请空间失败\n");
return NULL;
}
bzero(sqlist,sizeof(sqlist->data));
sqlist->len=0;
return sqlist;
}
void head_insert(list_p sqlist,int element)
{
//判断顺序表是否存在,是否有其他元素
if(sqlist==NULL)
{
printf("入参为空");
return ;
}
if(full_sq(sqlist))
{
printf("%d",sqlist->len);
printf("顺序表已满");
return;
}
//头部插入
for(int i=sqlist->len-1;i>=0;i--)
{
sqlist->data[i+1]=sqlist->data[i];
}
sqlist->data[0]=element;    
sqlist->len++;
}
void head_del(list_p sqlist)
{
if(sqlist==NULL)
{
printf("顺序表不存在\n");
return;
}
if(empty_sqlist(sqlist))
{
printf("顺序表为空,头删无效\n");
return;
}
for(int i=0;i<=sqlist->len-1;i++)
{
sqlist->data[i]=sqlist->data[i+1];
}
sqlist->len--;
}
void outputs(list_p sqlist)
{
//判断顺序表是否存在,是否有其他元素
if(sqlist==NULL)
{
printf("顺序表不存在\n");
return ;
}
if(empty_sqlist(sqlist))
{
printf("顺序表为空\n");
return;
}
for(int i=0;i<sqlist->len;i++)
{
printf("%d\t",sqlist->data[i]);
}
putchar(10);

}

                                                                main.c

#include "head.h"
int main(int argc, const char *argv[])
{
list_p sqlist=create_list();
int element;
//输入
for(int i=0;i<MAX;i++)
{
scanf("%d",&element);
//调用头插
head_insert(sqlist,element);
}
//调用输出
outputs(sqlist);
head_del(sqlist);
printf("after head_del:\n");
outputs(sqlist);
return 0;
}

                                                                head.h

#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 5
typedef struct
{
int data[MAX];
int len;    

}list,*list_p;

list_p create_list();
void head_insert(list_p sqlist,int element);
void outputs(list_p sqlist);
int full_sqlist(list_p sqlist);
void head_del(list_p sqlist);
#endif

3.在下列前提下,重新完成创建顺序表的函数

                                                                fun.c:

#include "head.h"
seq_p seq_create(seq_p *S)
{
*S=(seq_p)malloc(sizeof(seq_list));
if(*S==NULL)
{
printf("申请空间失败\n");
return NULL;
}
//长度置0
(*S)->len=0;    
return *S;
}
main.c:

#include "head.h"
int main(int argc, const char *argv[])
{
//定义一个结构体指针,指向堆区申请的顺序表的空间

    seq_p S;
if (seq_create(&S) != NULL) 
{
printf("顺序表创建成功,初始长度: %d\n", S->len);
}
return 0;
}
head.h

#ifndef __HEAD_H__
#define __HEAD_H__


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX 7
typedef struct 
{
int data[MAX];
int len;
}seq_list,*seq_p;
seq_p seq_create();
#endif

4.思维导图:

http://www.dtcms.com/a/343609.html

相关文章:

  • 【时时三省】集成测试 简介
  • GIS在城乡供水一体化中的应用
  • c#语言的学习【02,函数重载】
  • Java数据类型全解析:从基础到进阶的完整指南
  • leetcode-python-349两个数组的交集
  • 快速了解图像形态学
  • Huggingface 的介绍,使用
  • 人体生理参数信号采集项目——心电信号
  • actuary notes[4]
  • git 冲突解决方案
  • 组件卸载时useEffect状态
  • 人工智能驱动的现代电商前端开发:从基础到智能体验
  • 网易测试岗位--面试真题分析
  • 利用 Java 爬虫获取淘宝商品评论实战指南
  • 大语言模型原理(Transformer架构)
  • 高可用操作步骤
  • FP4层与NF4层 4位量化总结(49)
  • 实践题:数据采集与处理培训大纲
  • JavaWeb(五)转发、重定向、Get、POST
  • 在JAVA中如何给Main方法传参?
  • java开发面试题(提高篇)
  • 2026 济南玉米及淀粉深加工展:从原料到创新产品的完整解决方案
  • 【算法精练】 哈夫曼编码
  • Eino 框架组件协作指南 - 以“智能图书馆建设手册”方式理解
  • Excel中运行VB的函数
  • Sklearn 机器学习 房价预估 线性回归模型实现预估
  • 【自用】JavaSE--网络通信
  • 项目架构分享 —— 离线数仓
  • 【neo4j】安装使用教程
  • 最新react,vue 解决无法使用js触发点击,解决方案