C语言:通讯录(文件操作+动态内存管理) 简易版

news2024/9/24 13:16:08

目录

前言

一,通讯录菜单

二,通讯录菜单主函数

1.使用枚举:

2.主函数:

三,通讯录功能实现

1.创建通讯录

2.初始化通讯录

3,添加联系人

4,删除联系人

5,搜索联系人

6,打印通讯录

7.动态增容代码

8.保存本次通讯录

9.销毁存的通讯录

四,成品

1.contact.h

2.contact.c

3.test.c 


前言

本文将对通讯录菜单,通讯录菜单,添加联系人,删除联系人,搜索联系人,打印通讯录进行讲解(即1 2 3 6 0选项)

将分成三个文件:

        test.c //代码测试

        contact.h  // 函数声明

        contact.c // 函数主体 

 使用的自定义函数:

    //通讯录初始化
	void InitContact(Contact* pc);

	//增加用户
	void AddContact(Contact* pc);

	//打印个人信息
	void PrintContact(Contact* pc);

	//删除指定联系人
	void DelContect(Contact* pc);

	//查找联系人
	void SearchContect(const Contact* pc);

	//保存联系人
	void SaveContact(const Contact* pc);
	//动态增容代码
	void CheckCapacity(Contact* pc);

	//保存本次通讯录
	void LoadContact(Contact* pc);

	//销毁存的通讯录
	void DestroyContact(Contact* pc);

一,通讯录菜单

//test.c
void menu()
{
	printf("************************************\n");
	printf("********* 1.add    2.del    ********\n");
	printf("********* 3.search 5.modify ********\n");
	printf("********* 5.sort  6.print   ********\n");
	printf("*********     0.exit        ********\n");
	printf("************************************\n");
	printf("************************************\n");

}

二,通讯录菜单主函数

对菜单的进行选择,使选项进入函数

1.使用枚举:

使用枚举函数是为了编写代码时使选项可视化,避免编译错选项

//test.c

//使用枚举精选选择
enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
};

2.主函数:

void menu()
{
	printf("************************************\n");
	printf("********* 1.add    2.del    ********\n");
	printf("********* 3.search 5.modify ********\n");
	printf("********* 5.sort  6.print   ********\n");
	printf("*********     0.exit        ********\n");
	printf("************************************\n");
	printf("************************************\n");

}
void test()
{

	int option = 0;

	//创建通讯录
	Contact con;

	//通讯录初始化
	InitContact(&con);

	//对选择项进行判断
	do
	{
		menu();

		scanf("%d", &option);//选择要进行的业务
		switch (option)
		{

		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContect(&con);
			break;
		case SEARCH:
			SearchContect(&con);
			break;
		case MODIFY:

			break;
		case SORT:

			break;
		case PRINT:
			PrintContact(&con);
			break;
		case EXIT:
			//通讯录销毁前对通讯录用户信息进行保存
			SaveContact(&con);
			// 退出通讯录时,进行销毁  释放内存	
			DestroyContact(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误\n");
			break;

		}
	} while (option);
}

int main()
{
	test();

	return 0;
}

三,通讯录功能实现

1.创建通讯录

//contact.h
 
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

//    常量定义便于调试时更改
//#define MAX 1000 静态用常量
#define NAME_MAX 20  //名字最大长度
#define SEX_MAX 5    //性别
#define TELE_MAX 12  //电话号码
#define ADDR_MAX 30  //地址

//通讯录初始状态的容量大小 (动态通讯录)
#define DEFAULT_SZ 3

//通讯录填写格式
typedef struct  PeoInfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;

//通讯录信息

// 静态版本
//typedef struct Contact
//{
//	PeoInfo data[MAX];//可以存放的人数
//	int sz;//记录保存信息个数
//}Contact;

//动态
typedef struct Contact
{
	PeoInfo* data;//可以存放的人数
	int sz;//记录保存信息个数
	int capacity;//记录通讯录最大容量
}Contact;

2.初始化通讯录

//contact.h

//通讯录初始化
void InitContact(Contact* pc);
//contact.c

//通讯录初始化

//动态+ 文件版本
void InitContact(Contact* pc)
{
	//断言
	assert(pc);

    //保存信息和储存个数初始化
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;

	//申请空间
	pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact::malloc");//错误原因
	}
	//用memeset函数初始化数组
	memset(pc->data, 0, pc->capacity * sizeof(pc->data));

	//加载文件信息到通讯录中
	LoadContact(pc);// (后文会出现)
}

//静态版本
void InitContact(Contact* pc)
{
	//断言
	assert(pc);
	pc->sz = 0;
	//用memeset函数初始化数组
	memset(pc->data, 0, sizeof(pc->data));
}

//动态版本
void InitContact(Contact* pc)
{
	//断言
	assert(pc);
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
	//申请空间
	pc->data = (int*)malloc(pc->capacity * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact::malloc");//错误原因
	}
	//用memeset函数初始化数组
	memset(pc->data, 0, pc->capacity * sizeof(pc->data));
}

3,添加联系人

 //contact.h

//增加用户
void AddContact(Contact* pc);
//contact.h

void AddContact(Contact* pc)
{
	//录入信息

	//静态版本   动态版本不存在满装填,接近就进行扩容
	//if (pc->sz == MAX)
	//{
	//	printf("通讯录已满,无法添加\n");
	//	return;
	//}

	//动态版本
	CheckCapacity(pc); //动态增加内存

	printf("输入名字:>");
	scanf("%s", pc->data[pc->sz].name);
	printf("输入年龄:>");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("输入性别:>");
	scanf("%s", pc->data[pc->sz].sex);
	printf("输入电话:>");
	scanf("%s", pc->data[pc->sz].tele);
	printf("输入地址:>");
	scanf("%s", pc->data[pc->sz].addr);

	pc->sz++;
	printf("添加成功\n");
}

4,删除联系人

//contact.h

//删除指定联系人
void DelContect(Contact* pc);
//contact.c

//删除指定联系人
void DelContect(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录已空,无法删除\n");
		return;
	}

	//删除 
	//1.找到要删除的人
	char name[NAME_MAX] = { 0 };
	printf("请输入要删除人的名字:>");
	scanf("%s", &name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
	}
	//2.删除 (使删除后面的数组向前后移一位)
	int j = 0;
	for (j = pos;j < pc->sz - 1; j++)
	{
		pc->data[j] = pc->data[j + 1];
	}
	pc->sz--;//防止越界访问	
	printf("删除成功\n");
}

5,搜索联系人

//contact.h

//查找联系人
void SearchContect(const Contact* pc);

//contact.c

//查找联系人
void SearchContect(const Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	printf("请输入要查找人的名字:>");
	scanf("%s", &name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
	}
	printf("%-20s %-3s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	printf("%-20s %-3d %-5s %-12s %-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex,
		pc->data[pos].tele, pc->data[pos].addr);
}

6,打印通讯录

  

//contact.h

//打印个人信息
void PrintContact(Contact* pc);
//contact.c

//保存联系人
void SaveContact(const Contact* pc)
{
	FILE* pf = fopen("contact.dat", "wb");
	if (pf == NULL)
	{
		perror("SaveContact::fopen");
		return;
	}
	int i = 0;
	for (i = 0;i < pc->sz;i++)
	{
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
	}
    //释放内存
	fclose(pf);
	pf = NULL;
}

7.动态增容代码

//contact.h

//动态增容代码
void CheckCapacity(Contact* pc);

//contact.c

//动态增容代码
void CheckCapacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		// 每次扩容增加两位
		PeoInfo* tmp = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));
		if (tmp != NULL)
		{
			pc->data = tmp;
		}
		else
		{
			perror("CheckCapacity::realloc");
			return;
		}
		pc->capacity += 2;
		//printf("增容成功\n"); 测试是否增容成功
	}
}

8.保存本次通讯录

//contact.h

//保存本次通讯录
void LoadContact(Contact* pc);

//contact.c

//保存联系人
void SaveContact(const Contact* pc)
{
	FILE* pf = fopen("contact.dat", "wb");
	if (pf == NULL)
	{
		perror("SaveContact::fopen");
		return;
	}
	int i = 0;
	for (i = 0;i < pc->sz;i++)
	{
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
	}
	fclose(pf);
	pf = NULL;
}

9.销毁存的通讯录

//contact.h

//销毁存的通讯录
void DestroyContact(Contact* pc);
//contact.c

//销毁存的通讯录
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->capacity = 0;
	pc->sz = 0;
	pc->data = 0;
	printf("销毁成功\n");
}

四,成品

1.contact.h

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

//#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30

//通讯录初始状态的容量大小
#define DEFAULT_SZ 3


//通讯录填写格式
typedef struct  PeoInfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;

//通讯录信息

//动态
typedef struct Contact
{
	PeoInfo* data;//可以存放的人数
	int sz;//记录保存信息个数
	//int capacity = DEFAULT_SZ;;
	int capacity;//记录通讯录最大容量
}Contact;

//通讯录初始化
void InitContact(Contact* pc);

//增加用户
void AddContact(Contact* pc);

//打印个人信息
void PrintContact(Contact* pc);

//删除指定联系人
void DelContect(Contact* pc);

//查找联系人
void SearchContect(const Contact* pc);

//保存联系人
void SaveContact(const Contact* pc);
//动态增容代码
void CheckCapacity(Contact* pc);

//保存本次通讯录
void LoadContact(Contact* pc);

//销毁存的通讯录
void DestroyContact(Contact* pc);

2.contact.c

#define _CRT_SECURE_NO_WARNINGS 
#include "contact.h"
//函数实现

//保存本次通讯录
void LoadContact(Contact* pc)
{
	//打开文件
	FILE* pf = fopen("contact.dat", "wb+");
	if (pf == NULL)
	{
		perror("loadContact::fopen");
	}
	//读文件
	PeoInfo tmp = { 0 };
	while (fread(&tmp, sizeof(PeoInfo), 1, pf))
	{
		CheckCapacity(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}
//动态+ 文件版本
void InitContact(Contact* pc)
{
	//断言
	assert(pc);
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
	//申请空间
	pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact::malloc");//错误原因
	}
	//用memeset函数初始化数组
	memset(pc->data, 0, pc->capacity * sizeof(pc->data));

	//加载文件信息到通讯录中
	LoadContact(pc);
}
//动态增容代码
void CheckCapacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		// 每次扩容增加两位
		PeoInfo* tmp = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));
		if (tmp != NULL)
		{
			pc->data = tmp;
		}
		else
		{
			perror("CheckCapacity::realloc");
			return;
		}
		pc->capacity += 2;
		//printf("增容成功\n"); 测试是否增容成功
	}
}
//增加成员
void AddContact(Contact* pc)
{
	//录入信息

	//动态版本
	CheckCapacity(pc);

	printf("输入名字:>");
	scanf("%s", pc->data[pc->sz].name);
	printf("输入年龄:>");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("输入性别:>");
	scanf("%s", pc->data[pc->sz].sex);
	printf("输入电话:>");
	scanf("%s", pc->data[pc->sz].tele);
	printf("输入地址:>");
	scanf("%s", pc->data[pc->sz].addr);

	pc->sz++;
	printf("添加成功\n");
}
//打印个人信息
void PrintContact(Contact* pc)
{
	assert(pc);
	printf("%-20s %-3s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	int i = 0;
	for (i = 0;i < pc->sz;i++)
	{
		printf("%-20s %-3d %-5s %-12s %-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex,
			pc->data[i].tele, pc->data[i].addr);
	}
}

//寻找联系人
//找到返回下标 	找不到返回-1
int FindByName(const Contact* pc, char name[])
{
	assert(pc);
	int i = 0;
	for (i = 0;i < pc->sz;i++)
	{
		if (0 == strcmp(pc->data[i].name, name))
		{
			return i;
		}

	}
	return -1;
}

//删除指定联系人
void DelContect(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录已空,无法删除\n");
		return;
	}

	//删除 
	//1.找到要删除的人
	char name[NAME_MAX] = { 0 };
	printf("请输入要删除人的名字:>");
	scanf("%s", &name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
	}
	//2.删除 (使删除后面的数组向前后移一位)
	int j = 0;
	for (j = pos;j < pc->sz - 1; j++)
	{
		pc->data[j] = pc->data[j + 1];
	}
	pc->sz--;//防止越界访问	
	printf("删除成功\n");
}

//查找联系人
void SearchContect(const Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	printf("请输入要查找人的名字:>");
	scanf("%s", &name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
	}
	printf("%-20s %-3s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	printf("%-20s %-3d %-5s %-12s %-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex,
		pc->data[pos].tele, pc->data[pos].addr);
}

//保存联系人
void SaveContact(const Contact* pc)
{
	FILE* pf = fopen("contact.dat", "wb");
	if (pf == NULL)
	{
		perror("SaveContact::fopen");
		return;
	}
	int i = 0;
	for (i = 0;i < pc->sz;i++)
	{
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
	}
	fclose(pf);
	pf = NULL;
}

//销毁存的通讯录
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->capacity = 0;
	pc->sz = 0;
	pc->data = 0;
	printf("销毁成功\n");
}

3.test.c 

#include "contact.h"
//测试通讯录功能

//使用枚举精选选择
enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
};


void menu()
{
	printf("************************************\n");
	printf("********* 1.add    2.del    ********\n");
	printf("********* 3.search 5.modify ********\n");
	printf("********* 5.sort  6.print   ********\n");
	printf("*********     0.exit        ********\n");
	printf("************************************\n");
	printf("************************************\n");

}
void test()
{

	int option = 0;

	//创建通讯录
	Contact con;

	//通讯录初始化
	InitContact(&con);

	//对选择项进行判断
	do
	{
		menu();

		scanf("%d", &option);//选择要进行的业务
		switch (option)
		{

		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContect(&con);
			break;
		case SEARCH:
			SearchContect(&con);
			break;
		case MODIFY:

			break;
		case SORT:

			break;
		case PRINT:
			PrintContact(&con);
			break;
		case EXIT:
			//通讯录销毁前对通讯录用户信息进行保存
			SaveContact(&con);
			// 退出通讯录时,进行销毁  释放内存	
			DestroyContact(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误\n");
			break;

		}
	} while (option);
}

int main()
{
	test();

	return 0;
}

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

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

相关文章

SpringBoot面试题及答案整理

1、什么是 Spring Boot&#xff1f; 多年来&#xff0c;随着新功能的增加&#xff0c;spring 变得越来越复杂。访问spring官网页面&#xff0c;我们就会看到可以在我们的应用程序中使用的所有 Spring 项目的不同功能。如果必须启动一个新的 Spring 项目&#xff0c;我们必须添…

【MTI 6.S081 Lab】Page tables

【MTI 6.S081 Lab】Page tables Speed up system calls (easy)实验任务Hints哪些其它的系统调用能通过这个共享页面变得更快&#xff0c;请解释。解决方案分配和释放页面初始化结构 实验心得 Print a page table (easy)实验任务Hints根据图3-4从文本中解释vmprint的输出。第0页…

机器学习:自动编码器Auto-encoder

Self-supervised Learning Framework 不用标注数据就能学习的任务&#xff0c;比如Bert之类的。但最早的方法是Auto-encoder。 Outline Auto-encoder encoder输出的向量&#xff0c;被decoder还原的图片&#xff0c;让输出的图片与输入的图片越接近越好。 将原始的高维向量变…

红黑树解密:为什么根节点必须是黑色,两个红色节点不能挨着?

红黑树解密&#xff1a;为什么根节点必须是黑色&#xff0c;两个红色节点不能挨着&#xff1f; 博主简介一、引言1.1、红黑树是什么及其特点1.2、根节点为黑色和红色节点不连续的性质介绍 二、为何根节点必须是黑色&#xff1f;三、为何两个红色节点不能挨着&#xff1f;总结 博…

PCB绘制时踩的坑 - SOT-223封装

SOT-223封装并不是同一的&#xff0c;细分的话可以分为两种常用的封装。尤其是tab脚的属性很容易搞错。如果你想着用tab脚连接有属性的铺铜&#xff0c;来提高散热效率&#xff0c;那么你一定要注意你购买的器件tab脚的属性。 第一种如下图&#xff0c;第1脚为GND&#xff0c;第…

Packet Tracer - 备份配置文件

Packet Tracer - 备份配置文件 目标 第 1 部分&#xff1a;与 TFTP 服务器建立连接 第 2 部分&#xff1a;从 TFTP 服务器传输配置 第 3 部分&#xff1a;将配置和 IOS 备份到 TFTP 服务器上 拓扑图 背景/场景 本练习旨在展示如何从备份恢复配置&#xff0c;然后执行新的…

Stephen Wolfram:神经网络

Neural Nets 神经网络 OK, so how do our typical models for tasks like image recognition actually work? The most popular—and successful—current approach uses neural nets. Invented—in a form remarkably close to their use today—in the 1940s, neural nets …

如何查找网页的cookie【以两步路平台】

登录/注册账号【重要】 进入开发人员工具 刷新页面&#xff0c;发现“全部”对应的列表发生改变 找到列表首页的文本后缀.htm的信息&#xff0c;点开后查找网站的Cookie。 注意&#xff1a;Cookie必须在登陆后的才有效&#xff0c;并且每次爬取都需要重新查找更新Cookie&…

六、初始化和清理(1)

本章概要 利用构造器保证初始化方法重载 区分重载方法重载与基本类型返回值的重载无参构造器 this 关键字在构造器中调用构造器static 的含义 利用构造器保证初始化 "不安全"的编程是造成编程代价昂贵的罪魁祸首之一。有两个安全性问题&#xff1a;初始化和清理。…

redis和数据库双写不一致一般如何解决-面试

先介绍一下常规的几种做法 1、先删缓存&#xff0c;在改数据库 2、先改数据库&#xff0c;在删缓存 3、先改数据库&#xff0c;在改缓存 4、延迟双删&#xff08;先删缓存&#xff0c;再改数据库&#xff0c;延迟几百毫秒&#xff0c;再删缓存&#xff09;&#xff0c;此方…

通过gre隧道建立私有专用网络

Internet 配置 vlan 128 vlan 202 router1&#xff1a; router2&#xff1a; router1 ping router 2

一起学SF框架系列5.11-spring-beans-数据校验validation

在日常的项目开发中&#xff0c;应用在执行业务逻辑之前&#xff0c;为了防止非法参数对业务造成的影响&#xff0c;必须通过校验保证传入数据是合法正确的&#xff0c;但很多时候同样的校验出现了多次&#xff0c;在不同的层&#xff0c;不同的方法上&#xff0c;导致代码冗余…

map求和accumulate、参数互换

运行代码&#xff1a; //map求和accumulate、参数互换 #include"std_lib_facilities.h"istream& operator>>(istream& is, map<string, int>&mm) {string ss"";int ii0;is >> ss;if(is>>ii)mm[ss] ii;return is; }t…

VSCode中python代码输出中文乱码解决

前言 最近在vs code里面执行python脚本时&#xff0c;只有打印中文&#xff0c;就会乱码。 内容 先检查右下角编码集设置是否正确 检查右下角编码集设置是否正确 &#xff1a; 如果不是utf-8点击修改。 如果还是不行&#xff0c;就进行下面的操作 修改用户设置 路径&a…

【算法基础:动态规划】5.1 背包问题

文章目录 01背包例题&#xff1a;2. 01背包问题 完全背包例题&#xff1a;3. 完全背包问题 多重背包例题&#xff1a;4. 多重背包问题 I例题&#xff1a;5. 多重背包问题 II&#xff08;数据范围较大&#xff1a;二进制优化&#xff09; 分组背包例题&#xff1a;9. 分组背包问…

2023/7/29总结

项目&#xff1a; 这几天主要实现了评论的功能点: 还是有点小bug&#xff0c;还在更改中…… 修改个人中心的界面 接下来是把收藏完善&#xff0c;因为收藏需要用户自己创建一个新的收藏夹

iOS开发-转场动画切换界面(类似系统动画)

iOS开发-转场动画切换界面&#xff08;类似系统动画&#xff09; 在开发中&#xff0c;无论我们使用 push 还是 present 推出新的 viewcontroller 时&#xff0c;系统为了提高用户体验都会为我们默认加上一些过渡动画。但是开发中需要自定义过度动画效果。这里就需要用到了转场…

二十五章:用于弱监督语义分割的激活调节和重新校准方案

0.摘要 图像级弱监督语义分割&#xff08;WSSS&#xff09;是一项基础而具有挑战性的计算机视觉任务&#xff0c;有助于场景理解和自动驾驶。大多数现有方法利用基于分类的类激活图&#xff08;CAMs&#xff09;作为初始伪标签&#xff0c;但这些方法往往关注区分性的图像区域&…

Leetcode刷题---C语言实现初阶数据结构---单链表

1 删除链表中等于给定值 val 的所有节点 删除链表中等于给定值 val 的所有节点 给你一个链表的头节点head和一个整数val&#xff0c;请你删除链表中所有满足Node.valval的节点&#xff0c;并返回新的头节点 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[…

Tomcat 的使用(图文教学)

Tomcat 的使用&#xff08;图文教学&#xff09; 前言一、什么是Tomcat&#xff1f;二、Tomcat 服务器和 Servlet 版本的对应关系三、Tomcat 的使用1、安装2、目录介绍3、如何启动4、Tomcat 的停止5、如何修改 Tomcat 的端口号6、如何部暑 web 工程到 Tomcat 中6.1 方式一6.2 …