通讯录项目(用c语言实现)

一.什么是通讯录

通讯录是一种用于存储联系人信息的工具或应用程序。它是一种电子化的地址簿,用于记录和管理个人、机构或组织的联系方式,如姓名、电话号码、电子邮件地址和邮寄地址等。通讯录的目的是方便用户在需要时查找和联系他人。

通讯录通常以列表或表格的形式呈现,每个条目代表一个联系人。用户可以根据联系人的姓名、公司、职位或其他标识符来组织和排序通讯录。随着技术的发展,通讯录也可以与其他应用程序、设备或云服务同步,以确保联系人信息的备份和共享。

通讯录在个人生活和商业环境中都非常有用。个人可以使用通讯录存储家庭成员、朋友、同事和其他重要联系人的信息,以便随时与他们保持联系。在商业环境中,通讯录可以用于管理客户、供应商、合作伙伴和员工的联系信息,以便进行业务沟通和合作。

现代的通讯录应用程序通常具有许多高级功能,如快速搜索、批量导入和导出、分组管理、标签和备注、生日提醒、备份和恢复等。这些功能使通讯录更加强大和便捷,满足用户日常联系和管理联系人的需求。

二.通讯录的功能(简易)

1.允许用户添加、编辑和删除联系人信息,包括姓名、电话号码、电子邮件地址、邮寄地址等。

2.快速搜索:提供快速搜索功能,让用户可以根据姓名、公司、职位或其他标识符快速查找特定的联系人。

三.通讯录的函数实现

关于顺序表的补充:

typedef  PeoInfo SLDataType;
typedef struct SeqList
{SLDataType* a;int size;int capacity;
}SL;

用户的信息:

//前置声明
struct SeqList;
typedef struct SeqList contact;
//用户数据
typedef struct PersonInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tel[TEL_MAX];char addr[ADDR_MAX];
}PeoInfo;

实现通讯录项目需要的代码比较多,我们要使用分文件编写。具体内容我就不再赘述了,如果你还有疑问,可以去看我之前发的扫雷项目。

还有要注意的是此项目是基于顺序表封装,如果对顺序表有疑问,请看我的上一篇文章。

1.初始化联系人列表

程序开始时,可以初始化一个空的联系人列表。InitContact(contact* con):初始化通讯录函数。它接受一个指向contact结构体的指针,通过调用SLInit函数初始化通讯录列表,并打印初始化成功的消息。

//初始化通讯录
void SLInit(SL* ps)
{assert(ps);ps->a = (SLDataType*)malloc(INIT_CAPACITY * sizeof(SLDataType));assert(ps->a);ps->size = 0;ps->capacity = INIT_CAPACITY;
}
void InitContact(contact* con)
{SLInit(con);printf("通讯录初始化成功!\n");
}

2.添加联系人

用户可以输入联系人的姓名和电话号码,程序将该联系人添加到列表中。AddContact(contact* con):添加通讯录数据函数。它接受一个指向contact结构体的指针,通过用户输入获取姓名、年龄、性别、电话和地址信息,并调用SLPushBack函数将该联系人信息添加到通讯录列表中,最后打印添加成功的消息。

//添加通讯录数据
void AddContact(contact* con)
{PeoInfo x = { 0 };printf("请输入姓名\n");scanf("%s", x.name);printf("请输入年龄\n");scanf("%d", &x.age);printf("请输入性别\n");scanf("%s", x.sex);printf("请输入电话\n");scanf("%s", x.tel);printf("请输入地址\n");scanf("%s", x.addr);SLPushBack(con, x);printf("添加成功!\n");
}

3.删除联系人

用户可以输入要删除的联系人的姓名,程序将在列表中查找并删除该联系人的信息。DelContact(contact* con):删除通讯录数据函数。它接受一个指向contact结构体的指针,通过将通讯录列表的大小减1来删除最后一个联系人的信息,并打印删除成功的消息。

//删除通讯录数据
void DelContact(contact* con)
{(con->size)--;printf("删除成功!\n");
}

4.显示联系人列表

程序可以显示当前联系人列表中的所有联系人及其电话号码。ShowContact(contact* con):展示通讯录数据函数。它接受一个指向contact结构体的指针,通过遍历通讯录列表,逐个打印联系人的姓名、年龄、性别、电话和地址信息,并打印已全部显示的消息。

/展示通讯录数据
void ShowContact(contact* con) 
{assert(con);printf("姓名 年龄 性别 电话 地址\n");for (int i = 0; i < con->size; i++){printf("%-4s ", ((con->a) + i)->name);printf("%-4d ", ((con->a) + i)->age);printf("%-4s ", ((con->a) + i)->sex);printf("%-4s ", ((con->a) + i)->tel);printf("%-4s ", ((con->a) + i)->addr);printf("\n");}printf("已全部显示!\n");
}

5.查找联系人

用户可以输入要查找的联系人的姓名,程序将在列表中查找并显示该联系人的信息。FindContactname(contact* con):查找通讯录数据函数。它接受一个指向contact结构体的指针,通过用户输入要查找的联系人姓名,然后在通讯录列表中查找匹配的姓名并返回其索引值(下标)。如果找到了匹配的联系人,返回其下标;如果未找到匹配的联系人,返回-1。

//查找通讯录数据
int FindContactname(contact* con) 
{assert(con);printf("请输入联系人的名字\n");char j[NAME_MAX] = { 0 };scanf("%s", j);for (int i = 0; i < (con->size); i++){if (strcmp(((con->a) + i)->name, j) == 0)return i;}return -1;
}

6.修改联系人

用户可以输入要修改的联系人的姓名,程序将在列表中查找并允许用户修改该联系人的信息。ModifyContact(contact* con):修改通讯录数据函数。它接受一个指向contact结构体的指针,首先调用FindContactname函数查找要修改的联系人的下标,如果找到了匹配的联系人,则通过用户输入更新该联系人的姓名、年龄、性别、电话和地址信息。如果未找到匹配的联系人,打印未找到的消息。

//修改通讯录数据
void ModifyContact(contact* con)
{int i = FindContactname(con);if (i >= 0){printf("找到了,下标是%d\n", i);printf("请输入姓名\n");scanf("%s", ((con->a) + i)->name);printf("请输入年龄\n");scanf("%d", &(((con->a) + i)->age));printf("请输入性别\n");scanf("%s", ((con->a) + i)->sex);printf("请输入电话\n");scanf("%s", ((con->a) + i)->tel);printf("请输入地址\n");scanf("%s", ((con->a) + i)->addr);printf("\n");}elseprintf("未找到!\n");
}

7.销毁联系人列表

程序结束时,可以销毁联系人列表,释放内存空间。DestroyContact(contact* con):销毁通讯录数据函数。它接受一个指向contact结构体的指针,通过调用SLDestroy函数销毁通讯录列表,并打印销毁成功的消息。

void SLDestroy(SL* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}
//销毁通讯录数据
void DestroyContact(contact* con)
{SLDestroy(con);printf("销毁成功!\n");
}

四.通讯录的菜单实现

main()函数中,首先调用menu()函数打印菜单选项,然后通过动态内存分配创建一个contact结构体的指针p,并调用InitContact()函数初始化通讯录。

接下来,通过一个do-while循环,根据用户输入的选项执行相应的操作。根据用户输入的选项,调用相应的函数,如AddContact()添加联系人、DelContact()删除联系人、FindContactname()查找联系人、ModifyContact()修改联系人和ShowContact()显示通讯录。

循环终止条件是用户输入0,即选择退出通讯录。在循环结束后,调用DestroyContact()函数销毁通讯录,并打印成功退出通讯录的消息。

此程序通过菜单和用户输入实现了对通讯录的基本操作。用户可以根据菜单选项选择要执行的操作,直到选择退出通讯录为止。

#include"contact.h"
#include"SL.h"
void menu()
{printf("*************************\n");printf("1.添加联系人 2.删除联系人\n");printf("3.查找联系人 4.修改联系人\n");printf("5.显示通讯录 0.退出通讯录\n");printf("*************************\n");
}
int main()
{menu();int i = 0;contact* p = (contact*)malloc(sizeof(contact));InitContact(p);do {printf("请输入\n");scanf("%d", &i);switch (i){case 1:{AddContact(p);break;}case 2:{DelContact(p);break;}case 3:{int k = FindContactname(p);if (k >= 0){printf("找到了,下标是%d\n", k);printf("姓名 年龄 性别 电话 地址\n");printf("%-4s ", ((p->a) + k)->name);printf("%-4d ", ((p->a) + k)->age);printf("%-4s ", ((p->a) + k)->sex);printf("%-4s ", ((p->a) + k)->tel);printf("%-4s ", ((p->a) + k)->addr);printf("\n");}elseprintf("未找到!\n");break;}case 4:{ModifyContact(p);break;}case 5:{ShowContact(p);break;}default:{printf("输入错误,请重新输入!\n");break;}}} while (i);DestroyContact(p);printf("已成功退出通讯录\n");return 0;
}

五.通讯录的测试

1.菜单的显示

2.添加联系人

3.删除联系人

4.查找联系人

5.修改联系人

6.显示通讯录

7.删除通讯录

六.通讯录项目的源码

1.顺序表的源码

1.SL.h

SL.h头文件定义了SL数据结构,表示序列列表。它还定义了初始化、销毁、检查容量、推入和弹出列表中的元素、在特定位置插入和删除元素、以及更改给定位置的元素的函数原型。

#pragma once
#define INIT_CAPACITY 4
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"contact.h"
typedef  PeoInfo SLDataType;
typedef struct SeqList
{SLDataType* a;int size;int capacity;
}SL;
void SLInit(SL* ps);
void SLDestroy(SL* ps);
//void SLPrint(SL* ps);
void SLCheckCapacity(SL* ps);
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
//int SLFind(SL* ps, SLDataType x);
void SLChange(SL* ps, int pos, SLDataType x);

2.Sl.c

Sl.c文件包含了有关顺序表的函数,这些函数实现了一个简单的单链表数据结构,用于管理通讯录数据。通过链表操作函数,可以向链表中添加元素、删除元素、获取元素以及获取链表的大小。这些函数与contact.c文件中的功能函数一起使用,实现了对通讯录数据的管理和操作。

#include"SL.h"
void SLInit(SL* ps)
{assert(ps);ps->a = (SLDataType*)malloc(INIT_CAPACITY * sizeof(SLDataType));assert(ps->a);ps->size = 0;ps->capacity = INIT_CAPACITY;
}
void SLDestroy(SL* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}
//void SLPrint(SL* ps)
//{
//	assert(ps);
//	for (int i = 0; i < ps->size; i++)
//	{
//		printf("%d ", *((ps->a) + i));
//	}
//	printf("\n");
//}
void SLCheckCapacity(SL* ps)
{assert(ps);SLDataType* j = NULL;if (ps->size >= ps->capacity){j = realloc(ps->a, 2 * (ps->capacity) * sizeof(SLDataType));if (j){free(ps->a);ps->a = NULL;perror("fault:");}else {ps->a = j;}}assert(ps->a);
}
void SLPushBack(SL* ps, SLDataType x)
{SLCheckCapacity(ps);*((ps->a) + (ps->size)) = x;(ps->size)++;
}
void SLPopBack(SL* ps)
{(ps->size)--;
}
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);for (int i = (ps->size) - 1; i > 0; i--){*((ps->a) + i) = *((ps->a) + i - 1);}*(ps->a) = x;(ps->size)++;
}
void SLPopFront(SL* ps)
{assert(ps);for (int i = 0; i < ((ps->size) - 1); i++){*((ps->a) + i) = *((ps->a) + i + 1);}(ps->size)--;
}
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(pos <= ps->size + 1);assert(ps);SLCheckCapacity(ps);for (int i = (ps->size) - 1; i > pos; i--){*((ps->a) + i) = *((ps->a) + i - 1);}*(ps->a + pos) = x;(ps->size)++;
}
void SLErase(SL* ps, int pos)
{assert(pos <= ps->size + 1);assert(ps);for (int i = pos; i < ((ps->size) - 1); i--){*((ps->a) + i) = *((ps->a) + i + 1);}(ps->size)--;
}
//int SLFind(SL* ps, SLDataType x)
//{
//	assert(ps);
//	for (int i = 0; i < (ps->size); i++)
//	{
//		if (*((ps->a) + i) == x)
//			return i;
//	}
//	return -1;
//}
void SLChange(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos <= ps->capacity - 1);*((ps->a) + pos) = x;
}

2.通讯录的源码

1.contact.h

contact.h头文件定义了用于管理联系人列表的数据结构和函数原型。它包括了SL.h头文件,该头文件定义了序列列表的函数和数据结构。

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define NAME_MAX 100
#define SEX_MAX 7
#define TEL_MAX 12
#define ADDR_MAX 100
#include<string.h>
//前置声明
struct SeqList;
typedef struct SeqList contact;
//用户数据
typedef struct PersonInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tel[TEL_MAX];char addr[ADDR_MAX];
}PeoInfo;
//初始化通讯录
void InitContact(contact* con);
//添加通讯录数据
void AddContact(contact* con);
//删除通讯录数据
void DelContact(contact* con);
//展示通讯录数据
void ShowContact(contact* con);
//查找通讯录数据
int FindContactname(contact* con);
//修改通讯录数据
void ModifyContact(contact* con);
//销毁通讯录数据
void DestroyContact(contact* con);

2.contact.c

contact.c文件包含了许多功能函数共同实现了对通讯录数据的初始化、添加、删除、展示、查找、修改和销毁的操作。相应的函数实现了对通讯录数据结构的操作,并通过调用SL.h中的函数实现了具体的链表操作。

#include"contact.h"
#include"SL.h"
//初始化通讯录
void InitContact(contact* con)
{SLInit(con);printf("通讯录初始化成功!\n");
}
//添加通讯录数据
void AddContact(contact* con)
{PeoInfo x = { 0 };printf("请输入姓名\n");scanf("%s", x.name);printf("请输入年龄\n");scanf("%d", &x.age);printf("请输入性别\n");scanf("%s", x.sex);printf("请输入电话\n");scanf("%s", x.tel);printf("请输入地址\n");scanf("%s", x.addr);SLPushBack(con, x);printf("添加成功!\n");
}
//删除通讯录数据
void DelContact(contact* con)
{(con->size)--;printf("删除成功!\n");
}
//展示通讯录数据
void ShowContact(contact* con) 
{assert(con);printf("姓名 年龄 性别 电话 地址\n");for (int i = 0; i < con->size; i++){printf("%-4s ", ((con->a) + i)->name);printf("%-4d ", ((con->a) + i)->age);printf("%-4s ", ((con->a) + i)->sex);printf("%-4s ", ((con->a) + i)->tel);printf("%-4s ", ((con->a) + i)->addr);printf("\n");}printf("已全部显示!\n");
}
//查找通讯录数据
int FindContactname(contact* con) 
{assert(con);printf("请输入联系人的名字\n");char j[NAME_MAX] = { 0 };scanf("%s", j);for (int i = 0; i < (con->size); i++){if (strcmp(((con->a) + i)->name, j) == 0)return i;}return -1;
}
//修改通讯录数据
void ModifyContact(contact* con)
{int i = FindContactname(con);if (i >= 0){printf("找到了,下标是%d\n", i);printf("请输入姓名\n");scanf("%s", ((con->a) + i)->name);printf("请输入年龄\n");scanf("%d", &(((con->a) + i)->age));printf("请输入性别\n");scanf("%s", ((con->a) + i)->sex);printf("请输入电话\n");scanf("%s", ((con->a) + i)->tel);printf("请输入地址\n");scanf("%s", ((con->a) + i)->addr);printf("\n");}elseprintf("未找到!\n");
}
//销毁通讯录数据
void DestroyContact(contact* con)
{SLDestroy(con);printf("销毁成功!\n");
}

3.test.c

代码中的main()函数是程序的入口点。它显示一个菜单选项,用于管理联系人列表,并重复提示用户输入,直到用户选择退出程序。根据用户的输入,它调用相应的函数来执行所需的操作。

#include"contact.h"
#include"SL.h"
void menu()
{printf("*************************\n");printf("1.添加联系人 2.删除联系人\n");printf("3.查找联系人 4.修改联系人\n");printf("5.显示通讯录 0.退出通讯录\n");printf("*************************\n");
}
int main()
{menu();int i = 0;contact* p = (contact*)malloc(sizeof(contact));InitContact(p);do {printf("请输入\n");scanf("%d", &i);switch (i){case 1:{AddContact(p);break;}case 2:{DelContact(p);break;}case 3:{int k = FindContactname(p);if (k >= 0){printf("找到了,下标是%d\n", k);printf("姓名 年龄 性别 电话 地址\n");printf("%-4s ", ((p->a) + k)->name);printf("%-4d ", ((p->a) + k)->age);printf("%-4s ", ((p->a) + k)->sex);printf("%-4s ", ((p->a) + k)->tel);printf("%-4s ", ((p->a) + k)->addr);printf("\n");}elseprintf("未找到!\n");break;}case 4:{ModifyContact(p);break;}case 5:{ShowContact(p);break;}default:{printf("输入错误,请重新输入!\n");break;}}} while (i);DestroyContact(p);printf("已成功退出通讯录\n");return 0;
}

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

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

相关文章

AI预测体彩排3第1弹【2024年4月12日预测--第1套算法开始计算第1次测试】

前面经过多个模型几十次对福彩3D的预测&#xff0c;积累了一定的经验&#xff0c;摸索了一些稳定的规律&#xff0c;有很多彩友让我也出一下排列3的预测结果&#xff0c;我认为目前时机已成熟&#xff0c;且由于福彩3D和体彩排列3的玩法完全一样&#xff0c;我认为3D的规律和模…

Zookeeper的集群搭建和ZAB协议详解

Zookeeper的集群搭建 1&#xff09;zk集群中的角色 Zookeeper集群中的节点有三个角色&#xff1a; Leader&#xff1a;处理集群的所有事务请求&#xff0c;集群中只有一个LeaderFollwoer&#xff1a;只能处理读请求&#xff0c;参与Leader选举Observer&#xff1a;只能处理读…

vscode 连接远程服务器 服务器无法上网 离线配置 .vscode-server

离线配置 vscode 连接远程服务器 .vscode-server 1. .vscode-server下载 使用vscode连接远程服务器时会自动下载配置.vscode-server文件夹&#xff0c;如果远程服务器无法联网&#xff0c;则需要手动下载 1&#xff09;网址&#xff1a;https://update.code.visualstudio.com…

MVVM架构模式

目录 MVVM 数据绑定方式 实现方式 Model View ViewModel 数据绑定方式 vue&#xff1a;&#xff1a; 数据劫持和发布-订阅模式&#xff1a; Object.defineProperty() 方法来劫持&#xff08;监控&#xff09;各属性的 getter 、setter &#xff0c;并在数据&#xff08;对…

[大模型]Qwen1.5-4B-Chat WebDemo 部署

Qwen1.5-4B-Chat WebDemo 部署 Qwen1.5 介绍 Qwen1.5 是 Qwen2 的测试版&#xff0c;Qwen1.5 是基于 transformer 的 decoder-only 语言模型&#xff0c;已在大量数据上进行了预训练。与之前发布的 Qwen 相比&#xff0c;Qwen1.5 的改进包括 6 种模型大小&#xff0c;包括 0.…

【论文精读】 GPT,GPT-2,GPT-3:大力出奇迹

系列文章目录 【论文精读】Transformer&#xff1a;Attention Is All You Need 【论文精读】BERT&#xff1a;Pre-training of Deep Bidirectional Transformers for Language Understanding 文章目录 系列文章目录一、前言二、GPT&#xff08;一&#xff09;文章概览&#xf…

用Python编写GUI程序将JPEG文件按文件名顺序插入PDF文件

在Python编程中&#xff0c;处理文件和图像是常见的任务之一。最近&#xff0c;我遇到了一个有趣的问题&#xff1a;如何通过编写一个GUI程序来将一个文件夹中的JPEG文件按文件名顺序插入到一个新的PDF文件中&#xff1f;在这篇博客中&#xff0c;我将分享我使用Python、wxPyth…

智能工业电脑在智慧电力中实现全程实时监控与调控

可视化编程工业电脑在化工、石油、电力等行业过程控制领域扮演着越来越重要的角色。这些基于ARM架构设计的嵌入式工业计算机凭借其高性能、低功耗以及出色的实时处理能力&#xff0c;有效提升了各行业生产过程的安全性和效率。 钡铼技术ARMxy系列采用嵌入式Linux 系统开发的产品…

从零开始写 Docker(十)---实现 mydocker logs 查看容器日志

本文为从零开始写 Docker 系列第十篇&#xff0c;实现类似 docker logs 的功能&#xff0c;使得我们能够查查看容器日志。 完整代码见&#xff1a;https://github.com/lixd/mydocker 欢迎 Star 推荐阅读以下文章对 docker 基本实现有一个大致认识&#xff1a; 核心原理&#x…

Harmony鸿蒙南向外设驱动开发-Codec

功能简介 OpenHarmony Codec HDI&#xff08;Hardware Device Interface&#xff09;驱动框架基于OpenMax实现了视频硬件编解码驱动&#xff0c;提供Codec基础能力接口给上层媒体服务调用&#xff0c;包括获取组件编解码能力、创建组件、参数设置、数据的轮转和控制、以及销毁…

关于QEMU模拟器本身以及和CXL功能模拟相关内容的学习

前言&#xff1a;在写Paper的时候&#xff0c;发现直接引用QEMU官网关于QEMU的介绍实在是一个图省事儿的方法&#xff0c;但是并不可取。即使是一小段&#xff0c;也要去真正了解QEMU的基本原理&#xff0c;如何实现功能模拟&#xff0c;以及目前实现的与CXL相关的内容。 注&am…

Apache中间件漏洞

目录 什么是Apache Apache文件上传&#xff08;CVE-2017-15715&#xff09; Apache后缀解析 什么是Apache Apache(音译为阿帕奇)是世界使用排名第一的Web服务器软件。它可以运行在几乎所有广泛使用的计算机平台上&#xff0c;由于其跨平台和安全性被广泛使用&#xff0c;是最…

景芯2.5GHz A72训练营dummy添加(一)

景芯A72做完布局布线之后导出GDS&#xff0c;然后进行GDS merge&#xff0c;然后用Calibre对Layout添加Dummy。在28nm以及之前的工艺中&#xff0c;Dummy metal对Timing的影响不是很大&#xff0c;当然Star RC也提供了相应的解决方案&#xff0c;可以考虑Dummy metal来抽取RC。…

03-JAVA设计模式-享元模式

享元模式 什么是享元模式 享元模式&#xff08;Flyweight Pattern&#xff09;是一种对象结构型设计模式&#xff0c;用于减少创建对象的数量&#xff0c;以减少内存占用和提高系统性能。它通过共享已经存在的对象来避免创建大量相似的对象&#xff0c;从而降低内存消耗。 在…

韦东山freeRTOS第一天课程笔记

文章目录 一、课程目标二、堆和栈三、创建freertos任务 一、课程目标 双架构 ARM&#xff1a; 目前主流的架构&#xff0c;用得最广&#xff0c;芯片公司需要付费购买&#xff0c;再搭配各种模块才能设计出芯片。 RISC-V&#xff1a; 后起之秀&#xff0c;开源、免费。 双系统…

【考研数学】《660》+《880》高分搭配方法

&#x1f4dd;《660题》和《880题》高效刷题方法 1️⃣做题要有针对性&#xff0c;不要为了做题而做题 &#x1f4aa;660和880题虽然多&#xff0c;但是你不用全都做完&#xff0c;你可以把它当成是题源&#xff0c;里面的每一道题都很经典&#xff0c;如果搞懂一道&#xff…

练习6 beach beauty

文章目录 图片展示 图片展示

第十三章 OpenGL ES-RGB、HSV、HSL模型介绍

第十三章 OpenGL ES-RGB、HSV、HSL模型详细介绍 第一章 OpenGL ES 基础-屏幕、纹理、顶点坐标 第二章 OpenGL ES 基础-GLSL语法简单总结 第三章 OpenGL ES 基础-GLSL渲染纹理 第四章 OpenGL ES 基础-位移、缩放、旋转原理 第五章 OpenGL ES 基础-透视投影矩阵与正交投影矩阵…

Java基础第十课——类与对象(1)

前面二白的九讲属于Java基础方面的内容&#xff0c;总体来说偏基础和简单&#xff0c;能完成的操作也有限&#xff0c;有兴趣的同学可以写一写相关的管理系统&#xff0c;后面二白也会上传一些自己敲的小系统&#xff0c;下面就要开始Java面对对象的知识内容了&#xff0c;从这…

特别详细的Spring Cloud 系列教程2:微服务网关gateway的启动

继上一篇&#xff1a;特别详细的Spring Cloud 系列教程1&#xff1a;服务注册中心Eureka的启动 在比较多的教程和书籍里&#xff0c;spring cloud的微服务网关用的Zuul。然而&#xff0c;zuul已经不被官方提倡&#xff0c;现在提倡用的是spring cloud gateway。因为gateway的整…