【(数据结构)—— 基于单链表实现通讯录】

news2024/11/17 15:47:22

(数据结构)—— 基于单链表实现通讯录

  • 一.通讯录的功能介绍
    • 1.基于单链表实现通讯录
      • (1). 知识要求
      • (2). 功能要求
  • 二.通讯录的代码实现
    • 1.通讯录的底层结构(单链表)
      • (1).思路展示
      • (2).底层代码实现(单链表)
        • 1.单链表头文件 —— (函数的定义)
        • 2.单链表的源文件 ——(函数的实现)
    • 2.通讯录上层代码实现(通讯录结构)
      • (1)思路展示
      • (2) 上层代码的实现(顺序表)
        • 1.通讯录的头文件 —— (函数的定义)
        • 2.通讯录的源文件 —— (函数的实现)
        • 3.测试源文件 —— (功能函数的测试运行)
    • 3.通讯录代码运行展示(数据只用于测试,无实际意义)
      • (1) 测试展示
      • (2) 总结升华

一.通讯录的功能介绍

1.基于单链表实现通讯录

(1). 知识要求

C语言基础要求:结构体、动态内存管理、单链表、文件件操作

(2). 功能要求

1)至少能够存储100个人的通讯信息
2)能够保存用户信息:名字、性别、年龄、电话、地址等
3)增加联系人信息
4)删除指定联系人
5)查找制定联系人
6)修改指定联系人
7)显示联系人信息

二.通讯录的代码实现

1.通讯录的底层结构(单链表)

(1).思路展示

由于,通讯录是基于单链表实现的,所以掌握基本的单链表的结构代码,非常重要~!

(2).底层代码实现(单链表)

1.单链表头文件 —— (函数的定义)
SList.h
#pragma once
#include"contact.h"
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

//创建链表节点结构
typedef struct ContactInfo SLDatatype;
typedef struct SListNode
{
	SLDatatype data;//要保存的数据
	struct SListNode* next;
}SLNode;

//创建几个节点组成链表,并且打印链表
//打印
void SLNPrint(SLNode* phead);

//尾插
void SLNPushBack(SLNode** pphead, SLDatatype x);
//头插
void SLNPushFront(SLNode** pphead, SLDatatype x);
//尾删
void SLNPopBack(SLNode** pphead);
//头删
void SLNPopFront(SLNode** pphead);
//在指定位置插入删除
// 
//查找指定的pos
SLNode* SLNFind(SLNode** pphead, SLDatatype x);
//在指定位置之前插入
void SLNInsrt(SLNode** pphead, SLNode* pos, SLDatatype x);
//在指定位置之后插入删除
void SLNInsrtAfter(SLNode* pos, SLDatatype x);
//删除指定位置的数据
void SLNErase(SLNode** pphead, SLNode* pos);
//删除指定位置之后的数据
void SLNEraseAfter(SLNode* pos);
//销毁链表
void SLNDestroy(SLNode** pphead);
2.单链表的源文件 ——(函数的实现)
SList.c
#include"SList.h"
//打印
//void SLNPrint(SLNode* phead)
//{
//	//循环打印
//	//可以用phead直接来访问,但是注意,当代码走到
//	//第16行的时候,此时phead已经变成NULL了
//	//若代码没写完,我还要继续使用指向第一个节点的地址时,这时我就
//	//找不到第一个节点的地址
//	//所以为了避免第一个节点被更改,要定义一个新的来代替
//	SLNode* pcur = phead;
//	while (pcur)
//	{
//		printf("%d ->", pcur->data);
//		pcur = pcur->next;
//	}
//	printf("NULL\n");
//}
//创建新的节点
SLNode* SLByNode(SLDatatype x)
{
	//开辟新的空间
	SLNode* node = (SLNode*)malloc(sizeof(SLNode));
	node->data = x;
	node->next = NULL;
	return node;
}
//尾插
void SLNPushBack(SLNode** pphead, SLDatatype x)
{
	SLNode* node = SLByNode(x);
	//判断链表是否为空,如果为空,直接插入
	if (*pphead == NULL)
	{
		*pphead = node;
		return;
	}

	//说明链表不为空 ,找尾
	SLNode* pcur = *pphead;
	while (pcur->next != NULL)
	{
		pcur = pcur->next;
	}
	pcur->next = node;

}

//头插
void SLNPushFront(SLNode** pphead, SLDatatype x)
{
	//创建新的节点
	SLNode* node = SLByNode(x);
	//让新的节点跟头节点连起来
	node->next = *pphead;
	//再让新节点成为头节点
	*pphead = node;

}

//尾删
void SLNPopBack(SLNode** pphead)
{
	//先判断链表是否为空,如果为空就无法进行删除操作
	assert(pphead);
	//还要判断第一个节点不能为空
	assert(*pphead);
	//只有一个节点的情况
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
		return;
	}
	//有多个节点的情况
	//先找到尾节点/尾节点的前一个节点
	SLNode* ptail = *pphead;
	SLNode* prev = NULL;
	while (ptail->next)
	{
		prev = ptail;
		ptail = prev->next;
	}
	//让尾节点的前一个节点指向不再指向尾节点,而是指向尾节点的下一个节点 
	prev->next = ptail->next;
	//然后在删除尾节点
	free(ptail);
	//为什么要将ptaii置为空指针?代码后面明明没有再使用ptail,因为打印链表的代码有判断节点的地址是否为空
	ptail = NULL;

}

void SLNPopFront(SLNode** pphead)
{
	//判断链表不能为空
	assert(pphead);
	//判断头节点不能为空
	assert(*pphead);
	SLNode* del = *pphead;
	*pphead = (*pphead)->next;
	free(del);
	//出于代码规范
	del = NULL;

}


//查找指定的pos
//SLNode* SLNFind(SLNode** pphead, SLDatatype x)
//{
//	assert(pphead);
//	SLNode* pcur = *pphead;
//	while (pcur)
//	{
//		if (pcur->data == x)
//		{
//			return pcur;
//		}
//		pcur = pcur->next;
//	}
//	//出循环,代表没找到
//	return NULL;
//}
//在指定位置之前插入
void SLNInsrt(SLNode** pphead, SLNode* pos, SLDatatype x)
{
	SLNode* node = SLByNode(x);
	assert(pphead);
	assert(*pphead);
	//只有一个节点的情况 == pos就是头节点,直接进行头插
	if (pos == *pphead)
	{
		node->next = *pphead;
		*pphead = node;
		return;
	}
	//有多个节点的情况
	//找pos的前一个节点
	SLNode* prev = *pphead;
	while (prev->next != pos)
	{

		prev = prev->next;
	}
	//这里的插入节点的处理顺序可以调换
	prev->next = node;
	node->next = pos;

}

//在指定的位置之后插入
void SLNInsrtAfter(SLNode* pos, SLDatatype x)
{
	assert(pos);
	SLNode* node = SLByNode(x);
	// node  pos  node->next
	node->next = pos->next;
	pos->next = node;
}

//删除指定位置的节点
void SLNErase(SLNode** pphead, SLNode* pos)
{
	assert(pphead);
	assert(*pphead);
	assert(pos);
	if (pos == *pphead)
	{
		*pphead = (*pphead)->next;
		free(pos);
		return;
	}

	//找pos的前一个节点
	SLNode* prev = *pphead;

	while (prev->next != pos)
	{
		prev = prev->next;
	}
	prev->next = pos->next;
	free(pos);
	pos = NULL;

}
//删除指定位置之后的节点
void SLNEraseAfter(SLNode* pos)
{
	assert(pos);
	assert(pos->next);
	SLNode* del = pos->next;
	pos->next = del->next;
	free(del);
	del = NULL;
}

//销毁链表
void SLNDestroy(SLNode** pphead)
{
	assert(*pphead);
	SLNode* pcur = *pphead;
	while (pcur)
	{
		SLNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	*pphead = NULL;
}

2.通讯录上层代码实现(通讯录结构)

(1)思路展示

1)由于,通讯录是基于单链表实现的。
2)所以,通讯录上层代码,只需要在上层代码的头文件代码中创建一个保存联系人的结构,然后再定义通讯录功能函数即可。
3)接着在通讯录上层代码的源文件中将这些功能函数实现即可。
4)基于前面,我们已经知道,通讯录是单链表实现的,所以在实现通讯录功能函数时,只需要在通讯录上层代码的源文件中,加上单链表的头文件就可以调运单链表的函数来实现通讯录了。

(2) 上层代码的实现(顺序表)

1.通讯录的头文件 —— (函数的定义)
contact.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>


#pragma once
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 15
#define ADDR_MAX 100

//前置声明
typedef struct SListNode contact;

//用户数据
typedef struct ContactInfo
{
        char name[NAME_MAX];
        char sex[SEX_MAX];
        int age;
        char tel[TEL_MAX];
        char addr[ADDR_MAX];
}CInfo;

//初始化通讯录
void InitContact(contact** pcon);
//添加通讯录数据
void AddContact(contact** pcon);
//删除通讯录数据
void DelContact(contact** pcon);
//展示通讯录数据
void ShowContact(contact* pcon);
//查找通讯录数据
void FindContact(contact* pcon);
//修改通讯录数据
void ModifyContact(contact** pcon);
//销毁通讯录数据
void DestroyContact(contact** pcon);

2.通讯录的源文件 —— (函数的实现)
contact.c
#include"contact.h"
#include"SList.h"


void LoadContact(contact** pcon) {
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL) {
		perror("fopen error!\n");
		return;
	}

	//循环读取文件数据
	CInfo info;
	while (fread(&info, sizeof(info), 1, pf))
	{
		SLNPushBack(pcon, info);
	}
	printf("历史数据导入通讯录成功!\n");
}
//初始化通讯录/建立头节点
void InitContact(contact** pcon)
{
	LoadContact(pcon);
}


//添加通讯录数据
void AddContact(contact** pcon)
{
	//接下来获取的都是结构体CInfo结构体里要求的数据
	CInfo info;
	printf("请输入联系人姓名:\n");
	scanf("%s", info.name);
	printf("请输入联系人性别:\n");
	scanf("%s", info.sex);
	printf("请输入联系人年龄:\n");
	scanf("%d", &info.age);
	printf("请输入联系人电话:\n");
	scanf("%s", info.tel);
	printf("请输入联系人住址:\n");
	scanf("%s", info.addr);
	
	//联系人数据都获取到了,并保存到了结构体info中
	//往通讯录(链表)中插入数据
	SLNPushBack(pcon, info);
}
contact* FindByName(contact* pcon, char name[])
{
	contact* cur = pcon;
	while (cur)
	{
		if (strcmp(cur->data.name, name) == 0) {
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
	
}

//删除通讯录数据
void DelContact(contact** pcon)
{
	//直接强制用户使用名称来查找
	printf("请输入要删除的联系人姓名:\n");
	char name[NAME_MAX];
	scanf("%s", name);
	contact* findidex = FindByName(*pcon, name);
	if (findidex)
	{
		(*pcon)->next = findidex->next;
		//找到了,要删除findidex位置的数据
		SLNErase(pcon, findidex);
		printf("删除成功\n");
	}
	else {
		printf("要删除的联系人不存在!\n");
		return;
	}
	
}
//展示通讯录数据
void ShowContact(contact* pcon)
{
	contact* cur;
		cur = pcon;
		//打印表头
		printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
		while (cur)
		{
			printf("%-5s %-5s %-4d %-4s %-4s\n",
				cur->data.name,
				cur->data.sex,
				cur->data.age,
				cur->data.tel,
				cur->data.addr);
			cur = cur->next;
		}
	
}
//查找通讯录数据
void FindContact(contact* pcon)
{
	//直接强制用户使用名称来查找
	printf("请输入你要查找的联系人\n");
	char name[NAME_MAX];
	scanf("%s", name);
	contact* findidex = FindByName(pcon, name);
	if (findidex==NULL)
	{
		printf("没有此联系人\n");
		return;
	}
	else
	{
		printf("找到了:\n");
		printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
		printf("%-5s %-5s %-4d %-4s %-4s\n",
			findidex->data.name,
			findidex->data.sex,
			findidex->data.age,
			findidex->data.tel,
			findidex->data.addr);
		
	}
}

//修改联系人选项
void MondifyMenu()
{
	printf("***************修改联系人选项****************\n");
	printf("***** 1.修改联系人名字  2.修改联系人性别*****\n");
	printf("***** 3.修改联系人年龄  4.修改联系人电话*****\n");
	printf("***** 5.修改联系人住址  0.退出删除选项*******\n");
	printf("******************************************\n");
}
//修改通讯录数据
void ModifyContact(contact** pcon)
{
	//直接强制用户使用名称来查找
	printf("请输入你要修改的联系人\n");
	char name[NAME_MAX];
	scanf("%s", name);
	contact* findidex = FindByName(*pcon, name);
	if (findidex == NULL)
	{
		printf("没有你要删除的联系人\n");
		return;
	}
	else {
		printf("找到了:\n");
		printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
		printf("%-5s %-5s %-4d %-4s %-4s\n",
			findidex->data.name,
			findidex->data.sex,
			findidex->data.age,
			findidex->data.tel,
			findidex->data.addr);

		int val = -1;
		do {
			MondifyMenu();
			printf("请选择你需要修改的信息:\n");
			scanf("%d", &val);
			switch (val)
			{
			case 1:
				printf("请输入修改后的联系人姓名:\n");
				scanf("%s", findidex->data.name);
				break;
			case 2:
				printf("请输入修改后的联系人性别:\n");
				scanf("%s", findidex->data.sex);
				break;
			case 3:
				printf("请输入修改后的联系人年龄:\n");
				scanf("%d", &findidex->data.age);
				break;
			case 4:
				printf("请输入修改后的联系人电话:\n");
				scanf("%s", findidex->data.tel);
				break;
			case 5:
				printf("请输入修改后的联系人住址:\n");
				scanf("%s", findidex->data.addr);
				break;
			case 0:
				printf("修改成功\n");
				printf("已退出删除联系人选项\n");
				break;
			default:
				printf("没有找到要修改的选项 请重新选择:\n");
				break;
			}

		} while (val != 0);

	}

}
void SaveContact(contact* pcon) {
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL) {
		perror("fopen error!\n");
		return;
	}
	//将通讯录数据写入文件
	contact* cur = pcon;
	while (cur)
	{
		fwrite(&(cur->data), sizeof(cur->data), 1, pf);
		cur = cur->next;
	}

	printf("通讯录数据保存成功!\n");
}

void DestroyContact(contact** pcon) {
	SaveContact(*pcon);
	SLNDestroy(pcon);
}
3.测试源文件 —— (功能函数的测试运行)
test.c
#include"contact.h"
#include"SList.h"

void menu()
{
	printf("***************通讯录****************\n");
	printf("***** 1.添加联系人  2.删除联系人*****\n");
	printf("***** 3.修改联系人  4.查找联系人*****\n");
	printf("***** 5.查看通讯录  0.退出通讯录*****\n");
	printf("*************************************\n");
}

int main()
{

	int op = -1;
	contact* con=NULL;
	InitContact(&con);
	do {
		menu();
		printf("请选择你要进行的操作:\n");
		scanf("%d", &op);
		switch (op)
		{
		case 1:
			AddContact(&con);
			break;
		case 2:
			DelContact(&con);
			break;
		case 3:
			ModifyContact(&con);
			break;
		case 4:
			FindContact(con);
			break;
		case 5:
			ShowContact(con);
			break;
		case 0:
			printf("已退出通讯录\n");
			break;
		default:
			printf("系统里没有找到你需要进行的操作,请重新输入:\n");
			break;

		}
	} while (op != 0);
	DestroyContact(&con);

	return 0;
}

3.通讯录代码运行展示(数据只用于测试,无实际意义)

(1) 测试展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(2) 总结升华

这里只是展示基于单链表实现通讯录的大致框架,和一些基本功能,有兴趣,能力的小伙伴,也可以下去拓展一下通讯录的其他功能,优化的更加完善,美观的通讯录。
感谢学习!

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

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

相关文章

国旗升降系统程序及原理图资料

本文主要介绍国旗升降系统设计程序及原理图&#xff08;完整资料见文末链接&#xff09; 系统原理图如下&#xff0c;程序资料见文末 附完整资料链接 百度网盘链接: https://pan.baidu.com/s/1Q5J2J8LgVJ-hoeTSVP95_g?pwd3qkw 提取码: 3qkw

TypeScript 安装

TypeScript 的安装 在电脑上全局安装typescript 在确保电脑上已经安装了node.js的前提下&#xff0c;使用npm工具进行安装。 执行如下命令即可&#xff1a; (执行成功会&#xff0c;会安装当前发布的最新版本的typescript) npm install -g typescript如果是Linux or Mac 系统&…

2023年“绿盟杯”四川省大学生信息安全技术大赛

findme 下载附件打开无法正常显示 使用010editor打开发现CRC报错&#xff0c;很可能是高度被修改了 使用工具爆破图片正确的宽度和高度 这里工具自动修复的依旧不能正常打开显示 我们先对原来图片的高度进行修改 之后再使用工具进行修复&#xff0c;即可正常显示&#xff0c;…

JavaScript基础知识15——专业术语:语句和表达式

哈喽&#xff0c;大家好&#xff0c;我是雷工。 今天看到了JavaScript中的专业术语&#xff1a;语句和表达式&#xff0c;以下为学习笔记。 1、表达式概念&#xff1a; 表达式是可以被求值的代码&#xff0c;JavaScript引擎会将其计算出一个具体的结果。 示例&#xff1a; a…

数字图书馆和智慧图书馆区别

数字图书馆和智慧图书馆都是现代图书馆的发展趋势&#xff0c;但它们有以下区别&#xff1a; 1. 数字图书馆&#xff1a;是指将传统图书馆的资源、服务和技术经过数字化处理&#xff0c;以电子化形式进行保存、管理和利用的现代图书馆。数字图书馆主要集中在数字化内容的建设和…

【网络】HTTPS讲解(侧重于加密、秘钥、证书的讲解)

HTTPS讲解 前言正式开始安全HTTP和HTTPS的关系什么是加密和解密为什么要加密运营商劫持中间人 常⻅的加密⽅式对称加密⾮对称加密 数据摘要数字签名HTTPS 的⼯作过程⽅案 1 - 只使⽤对称加密&#xff08;不可靠&#xff09;⽅案 2 - 只使⽤⾮对称加密&#xff08;不可靠&#x…

JavaWeb——IDEA相关配置(Maven配置以及创建自己的第一个Maven项目)

写在前面&#xff1a; 笔者根据狂神说的javaweb视频&#xff0c;一步一步跟着配置IDEA中的Maven&#xff0c;在后面&#xff0c;笔者将讲述自己如何从0配置Maven以及创建自己的第一个Maven项目&#xff0c;笔者将自己的心路历程&#xff0c;包括配置的过程&#xff0c;都以文字…

二进制明文字符串加密:实现原理

二进制明文字符串加密:实现原理 背景 这里就不多做解释了&#xff0c;明文字符串暴露就是最好的逆向分析指引。无论是恶意攻击样本还是有一定安全需求的组件&#xff0c;直接暴露程序中的明文字符串会大幅降低外部的分析成本。所以需要在编译出的二进制中隐藏字符串。不过需要…

大数据技术学习笔记(二)—— Hadoop运行环境的搭建

目录 1 模版虚拟机准备1.1 修改主机名1.2 修改hosts文件1.3 修改IP地址1.3.1 查看网络IP和网关1.3.2 修改IP地址 1.4 关闭防火墙1.5 创建普通用户1.6 创建所需目录1.7 卸载虚拟机自带的open JDK1.8 重启虚拟机 2 克隆虚拟机3 在hadoop101上安装JDK3.1 传输安装包并解压3.2 配置…

最详细STM32,cubeMX外部中断

这篇文章将详细介绍 cubeMX外部中断的配置&#xff0c;实现过程。 文章目录 前言一、外部中断的基础知识。二、cubeMX 配置外部中断三、自动生成的代码解析四、代码实现。总结 前言 实验开发板&#xff1a;STM32F103C8T6。所需软件&#xff1a;keil5 &#xff0c; cubeMX 。实…

16 Transformer 的编码器(Encodes)——我在做更优秀的词向量

博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https://github.com/nickchen121/Pre-training-language-model 配套博客链接:https://www.cnblogs.com/nickchen121/p/15105048.html Transformer 框架 seq…

解决osg绘制场景时因Z冲突导致重影或闪烁等不正常情况

目录 1. 问题的提出 2. Z冲突&#xff08;z-fighting&#xff09;简介 2.1. Z冲突&#xff08;z-fighting&#xff09;产生的原因 2.2. 如何消除Z冲突&#xff08;z-fighting&#xff09; 3. 代码实现 1. 问题的提出 今天绘制了一个棋盘格&#xff0c;鼠标在棋盘格上单击…

基于springboot实现学生综合测评系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现学生综合测评系统演示 摘要 随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;学生综合测评系统也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;学校规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人…

基于Android系统PJSIP库植入g729编码

基于Android系统PJSIP库植入g729编码 前言操作步骤1.从仓库下载最新的 PJSIP。3.将你的PJSIP项目中的所有文件作为给定补丁中的目录。4.按照 pjproject-2.5.diff 的说明应用更改。5.构建。 前言 有时候由于工作的需求&#xff0c;我们需要基于Android系统的PJSIP库支持G.729编…

微信小程序三种授权登录以及授权登录流程讲解

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《微信小程序开发实战》。&#x1f3af;&#x1f3a…

链表专题回顾

移除链表元素 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 /*** Definition for singly-linked list.//注意基本的链表定义方法* public class ListNode {* int val;* List…

【C++】stackqueue

适配器是一种设计模式 &#xff0c; 该种模式是将一个类的接口转换成客户希望的另外一个接口 。 虽然 stack 和 queue 中也可以存放元素&#xff0c;但在 STL 中并没有将其划分在容器的行列&#xff0c;而是将其称为 容器适配 器 &#xff0c;这是因为 stack 和队列只是对其他容…

系统架构之微服务架构

微服务架构 一.传统的单体架构与微服务架构的区别1.1 单体架构1.1.1 优点1.1.2 缺点 1.2 微服务架构1.2.1 优点1.2.2 面临的问题与挑战 二. 微服务架构模式方案2.1 聚合器微服务2.2 链式微服务2.3 数据共享微服务2.4 异步消息传递微服务 三. SOA与微服务的区别 微服务&#xff…

【数据分享】2022年我国30米分辨率的山体阴影数据(免费获取)

地形数据&#xff0c;也叫DEM数据&#xff0c;是我们在各项研究中最常使用的数据之一。之前我们分享过2022年哥白尼30米分辨率的DEM数据&#xff0c;该数据被公认为是全球最佳的开源DEM数据之一&#xff0c;甚至没有之一&#xff01;基于该数据我们处理得到2022年30米分辨率的坡…

flask入门(四)前后端数据传输

文章目录 1、flask后端接收来自前端的数据1&#xff09;如果前端提交的方法为POST2&#xff09;如果前段提交的方法是GET 2、flask后端向前端传数据3、案例参考文献 1、flask后端接收来自前端的数据 1&#xff09;如果前端提交的方法为POST 后端接收时的代码&#xff1a; xx…