C语言期末课程设计—【通讯录管理系统】让课程设计不再是痛苦

news2025/1/31 11:01:58

目录

摘要

第一章 绪论

1.1项目意义

1.2通讯录功能

第二章 详细设计与实现 

2.1 Contact程序运行流程图

2.2 AddContact(增加)函数流程图

2.3 DelContact(删除)函数流程图

2.4 SearchConact(查找)函数流程图

2.5 ModifyContact(修改)函数流程图

2.6 SortContact(排序)函数流程图

第三章 系统测试

3.1 菜单

3.2 增加联系人信息

3.3 删除联系人信息

3.4 查找联系人信息

 3.5 修改联系人信息

3.6 按联系人信息排序

 3.7 打印联系人信息

4.心得体会 

5. 源码

5.1 DynamicContact.h

5.2 DynamicContact.c


本篇博客是博主期末的C语言课程设计的作业,作为一个模板写出来和大家分享,大家按需借鉴

摘要

本文介绍了一个基于C语言的通讯录管理系统。该系统可实现联系人信息的添加、查找、修改、删除、显示和排序等功能,并且提供了简单易用的用户交互界面。使用C语言的结构体和指针来存储和管理联系人信息,并使用文件读写功能对联系人信息进行保存和访问。在程序设计阶段,我们使用了模块化设计,将不同功能划分为不同的函数,以提高程序的可读性和可维护性。

系统的交互界面简单明了,用户可以通过几个简单的输入命令实现对联系人信息的添加、删除、查找、修改等操作。所有操作都反映在一个可视化的菜单上,便于用户了解当前操作和系统状态。通讯录系统还能够执行一些其他实用的功能,如备份和还原联系人数据。

我们通过使用C语言的高效性和简单性,设计了一个易于使用和维护的通讯录管理系统,使其适用于广泛的用户群体。该系统可用于日常生活和工作中,帮助用户管理联系人信息,提高工作效率和准确性。对于初学者来说,本系统也是一个很好的C语言实践项目,可以帮助他们更加深入地了解C语言的结构体、指针和文件读写等概念和用法。

关键字:通讯录管理系统、功能、结构体、指针、文件读写


第一章 绪论

 C语言课程设计的目的,你开发的这个软件的意义,软件要实现什么功能。

 以上是要求,下面是模板

1.1项目意义

1.提高编程能力:通过实现通讯录管理系统,可以提高C语言编程能力,掌握C语言的基本语法和数据结构。

2.实践项目开发:实现通讯录管理系统是一个小型的项目开发,可以让学生在实践中掌握项目开发的流程和方法。

3.提高问题解决能力:在实现通讯录管理系统的过程中,会遇到各种问题,需要学生自己思考和解决,从而提高问题解决能力。

4.培养团队合作精神:通讯录管理系统可以分为多个模块,需要多人协作完成,可以培养学生的团队合作精神。

5.实现实用功能:通讯录管理系统是一个实用的小工具,可以帮助用户管理联系人信息,提高生活效率。

1.2通讯录功能

1. 添加联系人:输入联系人的姓名、电话、地址等信息,将其保存到通讯录中。

2. 显示联系人:将通讯录中所有联系人的信息显示出来。

3. 查找联系人:根据姓名或电话号码查找联系人,并显示其详细信息。

4. 修改联系人:根据姓名或电话号码查找联系人,并修改其信息。

5. 删除联系人:根据姓名或电话号码查找联系人,并从通讯录中删除。

6. 清空联系人:删除通讯录中所有联系人。

7. 保存联系人:将通讯录中的联系人信息保存到文件中。

8. 读取联系人:从文件中读取联系人信息,并添加到通讯录中。

9. 退出系统:退出通讯录管理系统。


第二章 详细设计与实现 

这部分是C语言实现通讯录系统设计部分的,各函数的流程图和整个项目的流程图

2.1 Contact程序运行流程图

2.2 AddContact(增加)函数流程图

2.3 DelContact(删除)函数流程图

2.4 SearchConact(查找)函数流程图

 

2.5 ModifyContact(修改)函数流程图

2.6 SortContact(排序)函数流程图


第三章 系统测试

3.1 菜单

3.2 增加联系人信息

3.3 删除联系人信息

3.4 查找联系人信息

 3.5 修改联系人信息

3.6 按联系人信息排序

 3.7 打印联系人信息


4.心得体会 

在实现通讯录管理系统的过程中,我学到了很多关于C语言编程的技巧和经验。以下是我的心得体会

1. 数据结构的选择很重要。在通讯录管理系统中,我使用了结构体来存储联系人的信息,这样可以方便地对联系人进行增删改查操作。

2. 内存管理要注意。在使用动态内存分配函数(如malloc和free)时,要注意及时释放内存,避免内存泄漏。

3. 错误处理很重要。在编写程序时,要考虑到各种可能出现的错误情况,并对其进行处理,以保证程序的稳定性和可靠性。

4. 模块化编程可以提高代码的可读性和可维护性。在编写通讯录管理系统时,我将不同功能的代码分成了多个模块,这样可以方便地对代码进行修改和维护。

5. 调试是编程过程中必不可少的一步。在编写通讯录管理系统时,我经常使用调试工具来查找程序中的错误,以便及时进行修复。

总之,通过实现通讯录管理系统,我不仅学到了很多关于C语言编程的技巧和经验,还提高了自己的编程能力和解决问题的能力。


5. 源码

5.1 DynamicContact.h

通讯录函数声明部分

#pragma once
#define _CRT_SECURE_NO_WARNINGS //vs 编译器需要,其他编译器不需要,可自行删去

//动态版通讯录

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

//类型声明

//PeoInit结构体所用
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
//通讯录初始状态的容量大小
#define DEFAULT_SZ 3

//枚举选项

enum Option //test函数所用的枚举
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
};

enum Modify //修改联系人所用的枚举
{
	EXIT0,
	NAME,
	SEX,
	AGE,
	TELE,
	ADDR
};

//结构体声明

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 count;//通讯录中已经保存的信息个数
	int capacity;//记录通讯录当前的最大容量
}Contact;


//函数声明

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

//销毁通讯录
void DestroyContact(Contact* p);

//添加联系人
void AddContact(Contact* p);

//删除联系人
void DelContact(Contact* p);

//查找联系人
void SearchContact(const Contact* p);

//修改联系人信息
void ModifyContact(Contact* p);

//打印联系人
void PrintContact(const Contact* p);

//排序
void SortContact(const Contact* p);

//保存通讯录的信息到文件
void SaveContact(const Contact* pc);

//加载文件信息到通讯录中
void LoadContact(Contact* p);

5.2 DynamicContact.c

通讯录功能实现部分

#include "DynamicContact.h"

//排序所用菜单
void menu2()
{
	printf("********************************\n");
	printf("******  1.name    2.age   ******\n");
	printf("******  0.exit            ******\n");
	printf("********************************\n");
}
//修改联系人所用的菜单
void menu1()
{
	printf("********************************\n");
	printf("******  1.name    2.sex   ******\n");
	printf("******  3.age     4.tele  ******\n");
	printf("******  5.addr    0.exit  ******\n");
	printf("********************************\n");

}

//检测通讯录容量
void CheckCapacity(Contact* p)
{
	assert(p);
	if (p->capacity == p->count)
	{
		PeoInfo* tmp = (PeoInfo*)realloc(p->data, (p->capacity + 2) * sizeof(PeoInfo));
		if (p->data != NULL)
		{
			p->data = tmp;
		}
		else
		{
			perror("CheckCapacity::realloc");
			return;
		}

		p->capacity += 2;
		printf("增容成功\n");
	}
}

//初始化通讯录
void InitContact(Contact* p)
{
	assert(p);
	p->count = 0;
	p->capacity = DEFAULT_SZ;
	p->data = (PeoInfo*)malloc(p->capacity * sizeof(PeoInfo));

	if (p->data == NULL)
	{
		perror("InitContact::malloc");
		return;
	}

	memset(p->data, 0, p->capacity * sizeof(PeoInfo));//把PeoInit全部初始化为0

	//加载文件信息到通讯录中
	LoadContact(p);
}

//销毁通讯录
void DestroyContact(Contact* p)
{
	free(p->data);
	p->data = NULL;
	p->capacity = 0;
	p->count = 0;

	printf("销毁成功\n");
}

//添加联系人
void AddContact(Contact* p)
{
	//检查容量
	CheckCapacity(p);

	//录入信息
	printf("请输入名字:>");
	scanf("%s", p->data[p->count].name);
	printf("请输入性别:>");
	scanf("%s", p->data[p->count].sex);
	printf("请输入年龄:>");
	scanf("%d", &(p->data[p->count].age));
	printf("请输入电话:>");
	scanf("%s", p->data[p->count].tele);
	printf("请输入地址:>");
	scanf("%s", p->data[p->count].addr);

	p->count++;
	printf("添加成功\n\n");
}

//查找,找到了返回下标,找不到返回 -1
int FindName(const Contact* p, char name[])
{
	assert(p);
	int i = 0;
	for (i = 0; i < p->count; i++)
	{
		if (0 == strcmp(p->data[i].name, name))
		{
			return i;
		}
	}
	return -1;
}

//删除联系人
void DelContact(Contact* p)
{
	assert(p);
	if (0 == p->count)
	{
		printf("通讯录已空,无法删除\n");
		return;
	}
	char name[NAME_MAX];
	printf("请输入要查找的名字:>");
	scanf("%s", name);
	int position = FindName(p, name);//查找
	if (-1 == position)
	{
		printf("要删除的联系人不存在\n\n");
		return;
	}
	//删除
	int i = 0;
	for (i = position; i < p->count - 1; i++)
	{
		p->data[i] = p->data[i + 1];
	}
	p->count--;
	printf("删除成功\n\n");
}

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

//修改联系人信息
void ModifyContact(Contact* p)
{
	assert(p);
	int intput = 0;
	char name[NAME_MAX];
	printf("请输入要修改联系人的名字:>");
	scanf("%s", name);
	int position = FindName(p, name);//查找
	if (-1 != position)
	{
		printf("\n-----------------------------------------------\n");
		printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%-10s %-5s %-5d %-12s %-30s\n", p->data[position].name, p->data[position].sex,
			p->data[position].age, p->data[position].tele, p->data[position].addr);
		printf("\n-----------------------------------------------\n\n");
		do
		{
			menu1();
			printf("请输入要修改的选项:>");
			scanf("%d", &intput);
			switch (intput)
			{
			case NAME:
				printf("请修改名字:>");
				scanf("%s", p->data[position].name);
				printf("修改成功\n\n");
				break;
			case SEX:
				printf("请修改性别:>");
				scanf("%s", p->data[position].sex);
				printf("修改成功\n\n");
				break;
			case AGE:
				printf("请修改年龄:>");
				scanf("%d", &(p->data[position].age));
				printf("修改成功\n\n");
				break;
			case TELE:
				printf("请修改电话号码:>");
				scanf("%s", p->data[position].tele);
				printf("修改成功\n\n");
				break;
			case ADDR:
				printf("请修改地址:>");
				scanf("%s", p->data[position].addr);
				printf("修改成功\n\n");
				break;
			case EXIT0:
				printf("退出修改\n\n");
				break;
			default:
				printf("选择错误,请重新选择\n\n");
				break;
			}
		} while (intput);
	}
	else
	{
		printf("所要修改的联系人不存在\n\n");
		return;
	}
}

//打印联系人
void PrintContact(const Contact* p)
{
	assert(p);
	int i = 0;
	printf("\n-----------------------------------------------\n");
	printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (i = 0; i < p->count; i++)
	{
		printf("%-10s %-5s %-5d %-12s %-30s\n", p->data[i].name, p->data[i].sex,
			p->data[i].age, p->data[i].tele, p->data[i].addr);
	}
	printf("-----------------------------------------------\n\n");
}


int cmp_name(const void* e1, const void* e2)
{
	return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}

int cmp_age(const void* e1, const void* e2)
{
	return (((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age);
}

//排序
void SortContact(const Contact* p)
{
	assert(p);
	int intput = 0;
	do
	{
		menu2();
		printf("请选择需要排序的选项:>");
		scanf("%d", &intput);
		switch (intput)
		{
		case 1:
			qsort(p->data, p->count, sizeof(struct PeoInfo), cmp_name);
			printf("按名字排序成功\n\n");
			break;
		case 2:
			qsort(p->data, p->count, sizeof(struct PeoInfo), cmp_age);
			printf("按年龄排序成功\n\n");
			break;
		case 0:
			printf("退出排序\n\n");
			break;
		default:
			printf("选择错误,请重新选择\n\n");
			break;
		}
	} while (intput);

}


//保存通讯录的信息到文件
void SaveContact(const Contact* p)
{
	//打开并创建文件
	FILE* pf = fopen("contact.data.txt", "w");//w:只写,
	if (pf == NULL)
	{
		perror("SaveContact::fopen");
		return;
	}

	//写文件
	int i = 0;
	for (i = 0; i < p->count; i++)
	{
		fwrite(p->data + i, sizeof(PeoInfo), 1, pf);
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
}

//加载文件信息到通讯录中
void LoadContact(Contact* p)
{
	//打开文件
	FILE* pf = fopen("contact.data.txt", "r");//r:只读
	if (pf == NULL)
	{
		perror("LoadContact::fopen");
		return;
	}


	//读文件
	PeoInfo tmp = { 0 };
	while (fread(&tmp, sizeof(PeoInfo), 1, pf))
	{
		CheckCapacity(p);
		p->data[p->count] = tmp;
		p->count++;
	}

	//关闭文件
	fclose(pf);
	pf = NULL;

}

5.3 test.c

通讯录系统设计测试部分

#include "DynamicContact.h"

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

}
void test()
{
	int intput = 0;
	Contact con;//创建通讯录
	InitContact(&con);//初始化通讯录
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &intput);
		switch (intput)
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SORT:
			SortContact(&con);
			break;
		case PRINT:
			PrintContact(&con);
			break;
		case EXIT:
			SaveContact(&con);//销毁通讯录之前把数据存入文件中
			DestroyContact(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("输入错误,请重新输入\n\n");
			break;
		}

	} while (intput);
}
int main()
{
	test();
	return 0;
}


本篇博客借鉴于博主枫叶先生,如果大家想学习本篇中的流程图画图方法和工具获取,可以前去关注这个博主!!!

如果觉得文章不错,期待你的一键三连哦,你个鼓励是我创作的动力之源,让我们一起加油,顶峰相见!!!

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

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

相关文章

碳排放预测模型 | Python实现基于机器回归分析的碳排放预测模型——数据清理和准备

文章目录 效果一览文章概述研究内容源码设计参考资料效果一览 文章概述 碳排放预测模型 | Python实现基于机器回归分析的碳排放预测模型——数据清理和准备 研究内容 分析国家在设计用于预测和预测二氧化碳排放的机器学习模型方面的特定记录,利用来自全球绝大多数国家的记录。…

Spring Cloud - 带你认识微服务,简单demo实现服务拆分及远程调用

目录 一、微服务 1.1、简介 1.2、架构工作原理 1.3、架构特点 1.4、简单了解 SpringCloud 二、服务拆分和远程调用 2.1、服务拆分 2.2、微服务远程调用 2.2.1、远程调用分析 2.2.2、具体调用步骤 三、小结 一、微服务 1.1、简介 微服务是一种架构风格&#xff0c;…

React学习之路-准备工作

一、3W React是什么&#xff1f; React 起源于 Facebook 的内部项目&#xff0c;因为该 公司对市场上所有 JavaScript MVC 框架&#xff0c;都不满意&#xff0c;就决定自己写一套&#xff0c;用来架设 Instagram 的网站。做出来以后&#xff0c;发现这套东西很好用&#xf…

linux 环境执行npm没有反应 (省流:卸载重装)

今天早上在执行工程 npm run dev 时&#xff0c;发现没有反应&#xff0c;也没有提示任何错误&#xff0c;就直接跳过了。 接着我又试了试其他命令 npm -v / npm init / npm … 都无效。 windows 下的解决方案 于是我上网查询了一番&#xff0c;发现的确也有其他人遇到这种…

虚函数表不一定总是在对象的起始位置

在我之前的一篇文章 “COM 对象的内存布局”中&#xff0c;作为举例&#xff0c;我将对象的虚函数表指针放置在了底层 C 对象的起始位置&#xff0c;但是值得注意的是&#xff0c;虚函数表指针指向的位置并没有一个实际的标准。即使将虚函数表放置在对象中间&#xff0c;甚至是…

计算机网络编程 | 并发服务器代码实现(多进程/多线程)

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

基于 Quivr 搭建个人知识库

目录 Quivr介绍 Quivr特性 Quivr演示 Demo with GPT3.5: Demo of the new version&#xff1a; Quivr实战 Quiv 使用的主要技术 Quiv 实践依赖 创建Supabase项目 部署Quiv项目 第一步&#xff1a;现在源码 第二步&#xff1a;设置环境变量 第三步&#xff1a;执行sql 第…

http1.0,http1.1,http2.0,http3.0 区别有哪些

20 世纪 60 年代&#xff0c;美国国防部高等研究计划署&#xff08;ARPA&#xff09;建立了 ARPA 网&#xff0c;这被认为是互联网的起源。70 年代&#xff0c;研究人员基于对 ARPA 网的实践和思考&#xff0c;发明出了著名的 TCP/IP 协议。该协议具有良好的分层结构和稳定的性…

Docker部署开源项目Django-CMS企业内容管理系统

Docker部署开源项目Django-CMS企业内容管理系统 一、Django-CMS介绍1.1 Django-CMS简介1.2 Django-CMS特点 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载django-cms-quic…

JS 之 事件Event对象详解(属性、方法、自定义事件)

一、Event对象 1、简介 ​ 事件event对象是指在浏览器中触发事件时&#xff0c;浏览器会自动创建一个event对象&#xff0c;其中存储了本次事件相关的信息&#xff0c;包括事件类型、事件目标、触发元素等等。浏览器创建完event对象之后&#xff0c;会自动将该对象作为参数传…

NLP——WordNet;Word Similarity; Word Sense Disambiguition

WordNet WordNet是一个广泛使用的英语词汇数据库和语义网络。它由普林斯顿大学认知科学实验室开发&#xff0c;旨在帮助人们理解单词之间的关系和意义。WordNet的主要目标是将英语词汇组织成一种层次结构&#xff0c;其中每个词都与其他相关词联系起来。WordNet中的单词按照它们…

[6]PCB设计实验|认识常用元器件|电阻器|18:30~19:00

目录 一、电阻器主要用途 1. 稳定和调节电路中的电流和电压 2. 作为分流、分压和负载使用 二、常见电阻器 1. 贴片电阻 2. 热敏电阻 3. 限流电阻 4. 可调电阻 5. 排阻(网络电阻) 三、几种常用电阻器的结构特点 四、电阻的参数 1. 额定功率 电阻器功率的表示 ​2…

自学黑客/网络安全工具软件大全100套

黑客工具软件大全100套 1 Nessus&#xff1a;最好的UNIX漏洞扫描工具 Nessus 是最好的免费网络漏洞扫描器&#xff0c;它可以运行于几乎所有的UNIX平台之上。它不止永久升级&#xff0c;还免费提供多达11000种插件&#xff08;但需要注册并接受EULA-acceptance–终端用户授权…

【六一儿童节】回忆一下“童年的记忆”

文章目录 [TOC](文章目录) 前言一、EasyX带我们步入了童话的世界1.1绘画哆啦A梦2.2绘画出来喜羊羊 二、我的六一故事总结 前言 我们都有过童年&#xff0c;并且从现在看来&#xff0c;童年是我们最希望可以回去的那段时光&#xff0c;那时候的我们傻傻的&#xff0c;并且很天真…

电子元器件解析02之电容(一)——定义与性能参数

下篇文章&#xff1a;电子元器件解析02之电容(二)——电容分类与应用场景&#xff1a;https://blog.csdn.net/weixin_42837669/article/details/131142767 摘要 电容是最基本的电子元器件之一&#xff0c;本文介绍了电容的定义&#xff0c;并总结了电容的各个性能参数&#xff…

leetcode143. 重排链表(java)

重排链表 leetcode143. 重排链表题目要描述 解题思路代码链表专题 leetcode143. 重排链表 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/reorder-list 题目要描述 给定一个单链表 L 的头节点 head &#xff0c;单链表 …

根据字节、华为、阿里、腾讯等大厂整理的2023最新面试热点问题,还不行我也救不了你了~

大厂面试热点问题 1、测试人员需要何时参加需求分析&#xff1f; 如果条件循序 原则上来说 是越早介入需求分析越好 因为测试人员对需求理解越深刻 对测试工作的开展越有利 可以尽早的确定测试思路 减少与开发人员的交互 减少对需求理解上的偏差 2、软件测试与调试的关系 测…

MM32F3273G8P火龙果开发板MindSDK开发教程11 -获取msa311加速器的xyz轴数据

MM32F3273G8P火龙果开发板MindSDK开发教程11 -获取msa311加速器的xyz轴数据 1、msa311简介 使用i2c总线 可以读取xyz轴的加速度 可以监测单击双击事件 可以监测运动与静止状态 可以监测自由落体事件&#xff0c;可用来监测摔倒或跌落。 可以监测旋转事件&#xff0c;类似手机…

工作中自我或者团队管理的几个有用工具

个人或者团队管理过程中&#xff0c;采用一些有效的管理工具或者方法&#xff0c;可以提升工作效率和结果。它们包括SMART原则、PDCA循环、SWOT分析、5W2H分析、鱼骨图分析、七个凡是。这几个工具或者方法之间有互通性&#xff0c;比如&#xff0c;PDCA循环中&#xff0c;在P这…

数学建模预备知识(1)全网最全的数学建模竞赛汇总,别再被坑了!

&#x1f305;*&#x1f539;** φ(゜▽゜*)♪ **&#x1f539;*&#x1f305; 欢迎来到馒头侠的博客&#xff0c;该类目主要讲数学建模的知识&#xff0c;大家一起学习&#xff0c;Qq及各类联系方式在图片上&#xff01; 喜欢的朋友可以关注下&#xff0c;下次更新不迷路&…