【数据结构】顺序表实操——通讯录项目

news2025/2/8 12:15:48

Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~
💥💥个人主页:奋斗的小羊
💥💥所属专栏:C语言

🚀本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为展示我的学习过程及理解。文笔、排版拙劣,望见谅。


目录

  • 前言
  • 1、创建结构体类型
  • 2、通讯录的初始化和销毁
  • 3、通讯录的增删查改
    • 3.1 添加联系人
    • 3.2 删除联系人
    • 3.3 展示联系人
    • 3.4 修改联系人
    • 3.5 查找联系人
  • 4、通讯录菜单
  • 5、通讯录项目代码
  • 总结

前言

本篇文章将介绍一个运用顺序表的例子——通讯录项目。
通讯录我们都知道,细细一想通讯录不就是一个顺序表吗?在通讯录中以一个联系人为单位,存储着若干个联系人的各种信息,我们也可以对通讯录中的联系人信息进行相应的增删查改操作。但是上篇文章的顺序表存的只是整型数据,而在本文联系人的信息可不只是整形数据,如果想把一个联系人的各种信息以一个联系人为单位存储,就需要用到我们之前学到的内置类型——结构体类型。
接下来将详细介绍基于顺序表的通讯录项目搭建的具体过程。
本文将延用上篇文章中实现好的顺序表代码,具体请看—>顺序表


1、创建结构体类型

我们需要存联系人的姓名、性别、年龄、电话、地址等信息,如果把联系人看作一个单位,就需要一个类型能将联系人的这些信息储存,我们很容易的就能想到自定义类型——结构体类型。
所以第一步我们需要创建一个结构体类型来保存联系人的这些信息。

#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100

typedef struct personinfo
{
	char name[NAME_MAX];
	char gender[GENDER_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}peoinfo;

我们将保存名字等信息的数组大小用宏代替,这样方便后续可能的更改。
创建好用于保存联系人信息的结构体类型后,接着就需要将顺序表头文件中的动态顺序表管理的数据类型替换掉,不要忘了包含相应的头文件。

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "contact.h"

//顺序表管理数据的类型
//typedef int sl_data_type;
typedef peoinfo sl_data_type;

//动态顺序表
typedef struct seqlist
{
	sl_data_type* arr;
	int size;//数据个数
	int capacity;//空间大小
}SL;

2、通讯录的初始化和销毁

我们操作通讯录,实际上就是操作顺序表

那么通讯录的初始化和销毁,实际上就是顺序表的初始化和销毁。
为了方便识别,我们在通讯录头文件中给struct seqlist重新改个名字就叫contact。要想使用顺序表头文件中的struct seqlist原本是需要在通讯录头文件包含顺序表头文件的,但是顺序表头文件中已经包含了通讯录头文件,而我们知道头文件是不能互相包含的,那为了在通讯录头文件中使用struct seqlist,需要在使用前进行前置类型声明。
contact.h:

//给顺序表改一个名字
typedef struct seqlist contact;//前置声明

//通讯录的初始化
void contact_init(contact* con);
//通讯录的销毁
void contact_destroy(contact* con);

contact.c:

#include "contact.h"
#include "seqlist.h"

//通讯录的初始化
void contact_init(contact* con)
{
	//通讯录的初始化实际就是顺序表的初始化
	sl_init(con);
}

//通讯录的销毁
void contact_destroy(contact* con)
{
	sl_destroy(con);
}

3、通讯录的增删查改

3.1 添加联系人

在通讯录中添加联系人实际上就是上篇文章中的在顺序表中插入一个整型数据,只不过在这里把一个联系人当作一个单位。
首先我们需要一个结构体变量来存联系人的各种信息,然后再将这个结构体变量插入到通讯录(顺序表)中,插入方式可以有多种。

//通讯录添加数据
void contact_add(contact* con)
{
	//获取用户输入的信息
	//将用户输入的信息存到结构体变量中
	peoinfo info;
	printf("请输入要添加的联系人姓名:\n");
	scanf("%s", info.name);
	printf("请输入要添加的联系人性别:\n");
	scanf("%s", info.gender); 
	printf("请输入要添加的联系人年龄:\n");
	scanf("%d", info.age);
	printf("请输入要添加的联系人电话:\n");
	scanf("%s", info.tel);
	printf("请输入要添加的联系人地址:\n");
	scanf("%s", info.addr);

	//将结构体数据插入到通讯录(顺序表)中
	sl_push_back(con, info);
}

测试:

void test()
{
	contact con;// == SL sl;
	contact_init(&con);
	contact_add(&con);
	contact_destroy(&con);
}

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

请添加图片描述

可以看到我们成功地添加了一个联系人。


3.2 删除联系人

删除联系人操作有个大前提,就是要删除的这个联系人必须存在,否则无法删除。
怎么判断要删除的这个联系人是否存在呢?
首先我们需要获取要删除的这个联系人的信息,然后在通讯录中查找,如果找到了就可以执行删除操作,如果没找到就不能进行删除操作。
联系人的信息有好几个,我们可以任意选择其中的一个信息来判断是否存在这个联系人。

int find_by_name(contact* con, char name[])
{
	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->arr[i].name, name))
		{
			//找到了
			return i;
		}
	}
	return -1;
}

//通讯录删除数据
void contact_delete(contact* con)
{
	//前提是要删除的这个联系人存在
	char name[NAME_MAX];
	printf("请输入您想删除的联系人姓名:\n");
	scanf("%s", name);
	int ret = find_by_name(con, name);
	if (ret < 0)
	{
		printf("联系人不存在!\n");
		//直接返回
		return;
	}
	
	//删除指定位置的数据
	sl_erase(con, ret);
	printf("删除成功!\n");
}

上面我们是通过联系人的姓名来判断是否存在这个联系人,姓名是字符串,比较字符串需要用到字符串比较函数strcmp,使用这个函数需要包含头文件<string.h>
如果找到匹配的姓名,则返回这个姓名对应联系人对应的下标,再调用顺序表中删除指定位置数据的函数删除这个联系人。

请添加图片描述


3.3 展示联系人

我们平时使用的通讯录是可以展示联系人的各种信息的,这里我们也简单地实现一下,将所有联系人的信息打印出来供使用者看。

//通讯录数据展示
void contact_show(contact* con)
{
	//打印表头
	printf("%2s %8s %8s %8s %8s\n", "姓名", "性别", "年龄", "电话", "地址");
	printf("———      ———      ———      ———      ———\n");
	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		printf("%2s %7s %7d %9s %9s\n", con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr);
	}
}

在这里插入图片描述


3.4 修改联系人

修改联系人信息也有个大前提,就是要修改的这个联系人必须存在,才能被修改。

//通讯录修改
void contact_modify(contact* con)
{
	//前提是要修改的联系人存在
	char name[NAME_MAX];
	printf("请输入要修改的联系人姓名:\n");
	scanf("%s", name);
	int ret = find_by_name(con, name);
	if (ret < 0)
	{
		printf("联系人不存在!\n");
		return;
	}

	//修改指定位置的数据
	printf("请输入新的姓名:\n");
	scanf("%s", con->arr[ret].name);
	printf("请输入新的性别:\n");
	scanf("%s", con->arr[ret].gender);
	printf("请输入新的年龄:\n");
	scanf("%d", &con->arr[ret].age);
	printf("请输入新的电话:\n");
	scanf("%s", con->arr[ret].tel);
	printf("请输入新的地址:\n");
	scanf("%s", con->arr[ret].addr);

	printf("修改成功!\n");
}

在这里插入图片描述


3.5 查找联系人

我们可以延用之前写好的根据联系人姓名来查找联系人的find_by_name函数。

//通讯录查找
void contact_find(contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人姓名:\n");
	scanf("%s", name);
	int ret = find_by_name(con, name);
	if (ret < 0)
	{
		printf("您要查找的联系人不存在!\n");
		return;
	}
	printf("%2s %8s %8s %8s %8s\n", "姓名", "性别", "年龄", "电话", "地址");
	printf("———      ———      ———      ———      ———\n");
	printf("%2s %7s %7d %9s %9s\n", con->arr[ret].name,
		con->arr[ret].gender,
		con->arr[ret].age,
		con->arr[ret].tel,
		con->arr[ret].addr);
}

请添加图片描述


4、通讯录菜单

在实现完通讯录的相关操作后,我们接着制作一个简易菜单。
这个方法我们以前使用过多次了,这里就不再赘述。
其中枚举类型定义在头文件contact.h中。

#include "seqlist.h"

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

int main()
{
	int input = 0;
	contact con;
	contact_init(&con);
	do
	{
		menu();
		printf("请选择您的操作:");
		scanf("%d", &input);
		switch (input)
		{
		case EXIT:
			printf("退出通讯录!\n");
			break;
		case ADD:
			contact_add(&con);
			break;
		case DELETE:
			contact_delete(&con);
			break;
		case MODIFY:
			contact_modify(&con);
			break;
		case FIND:
			contact_find(&con);
			break;
		case SHOW:
			contact_show(&con);
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}
	} while (input);

	//销毁通讯录
	contact_destroy(&con);

	return 0;
}

5、通讯录项目代码

seqlist.h:

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "contact.h"

//顺序表管理数据的类型
//typedef int sl_data_type;
typedef peoinfo sl_data_type;

//动态顺序表
typedef struct seqlist
{
	sl_data_type* arr;
	int size;//数据个数
	int capacity;//空间大小
}SL;

//顺序表初始化
void sl_init(SL* ps);
//头插
void sl_push_front(SL* ps, sl_data_type x);
//尾插
void sl_push_back(SL* ps, sl_data_type x);
//在指定位置之前插入数据
void sl_insert(SL* ps, int pos, sl_data_type x);
//头删
void sl_pop_front(SL* ps);
//尾删
void sl_pop_back(SL* ps);
//删除指定位置的数据
void sl_erase(SL* ps, int pos);
//顺序表的查找
int sl_find(SL* ps, sl_data_type x);
//顺序表打印
void sl_print(const SL sl);
//顺序表销毁
void sl_destroy(SL* ps);

seqlist.c:

#define  _CRT_SECURE_NO_WARNINGS

#include "seqlist.h"

void sl_init(SL* ps)
{
	ps->arr = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

//检查是否有空间允许插入数据
void check_capacity(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//为了处理capacity为0的问题
		sl_data_type* tmp = (sl_data_type*)realloc(ps->arr, newcapacity * sizeof(sl_data_type));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		ps->arr = tmp;
		tmp = NULL;
		ps->capacity = newcapacity;//及时更新空间大小
	}
}

void sl_push_front(SL* ps, sl_data_type x)
{
	assert(ps != NULL);
	check_capacity(ps);
	int i = 0;
	for (i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;
}

void sl_push_back(SL* ps, sl_data_type x)
{
	assert(ps != NULL);
	check_capacity(ps);
	ps->arr[ps->size++] = x;
}

void sl_insert(SL* ps, int pos, sl_data_type x)
{
	assert(ps != NULL);
	assert(pos >= 0 && pos <= ps->size);//确保指定的位置是有效的
	check_capacity(ps);
	int i = 0;
	for (i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	ps->size++;
}

void sl_pop_front(SL* ps)
{
	assert(ps != NULL);
	assert(ps->size != 0);//顺序表为空不能删除
	int i = 0;
	for (i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

void sl_pop_back(SL* ps)
{
	assert(ps != NULL);
	assert(ps->size != 0);//顺序表为空不能删除
	ps->size--;
}

void sl_erase(SL* ps, int pos)
{
	assert(ps != NULL);
	assert(ps->size != 0);//实际下面的断言侧面完成了这句代码
	assert(pos >= 0 && pos < ps->size);//确保指定的位置是有效的
	int i = 0;
	for (i = pos; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

//int sl_find(SL* ps, sl_data_type x)
//{
//	assert(ps != NULL);
//	int i = 0;
//	for (i = 0; i < ps->size; i++)
//	{
//		if (ps->arr[i] == x)
//		{
//			return i;
//		}
//	}
//	return -1;
//}


//void sl_print(const SL sl)
//{
//	int i = 0;
//	for (i = 0; i < sl.size; i++)
//	{
//		printf("%d ", sl.arr[i]);
//	}
//	printf("\n");
//}

void sl_destroy(SL* ps)
{
	assert(ps != NULL);
	if (ps->arr != NULL)//动态内存函数开辟了空间
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

contact.h:

#pragma once

#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100

enum contact
{
	EXIT,
	ADD,
	DELETE,
	MODIFY,
	FIND,
	SHOW
};

typedef struct personinfo
{
	char name[NAME_MAX];
	char gender[GENDER_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}peoinfo;

//给顺序表改一个名字
typedef struct seqlist contact;//前置声明

//通讯录的初始化
void contact_init(contact* con);
//通讯录的销毁
void contact_destroy(contact* con);
//通讯录添加数据
void contact_add(contact* con);
//通讯录删除数据
void contact_delete(contact* con);
//通讯录修改
void contact_modify(contact* con);
//通讯录查找
void contact_find(contact* con);
//通讯录数据展示
void contact_show(contact* con);

contact.c:

#define  _CRT_SECURE_NO_WARNINGS

#include "contact.h"
#include "seqlist.h"
#include <string.h>

//通讯录的初始化
void contact_init(contact* con)
{
	//通讯录的初始化实际就是顺序表的初始化
	sl_init(con);
}

//通讯录的销毁
void contact_destroy(contact* con)
{
	sl_destroy(con);
}

//通讯录添加数据
void contact_add(contact* con)
{
	//获取用户输入的信息
	//将用户输入的信息存到结构体变量中
	peoinfo info;
	printf("请输入要添加的联系人姓名:\n");
	scanf("%s", info.name);
	printf("请输入要添加的联系人性别:\n");
	scanf("%s", info.gender); 
	printf("请输入要添加的联系人年龄:\n");
	scanf("%d", &info.age);
	printf("请输入要添加的联系人电话:\n");
	scanf("%s", info.tel);
	printf("请输入要添加的联系人地址:\n");
	scanf("%s", info.addr);

	//将结构体数据插入到通讯录(顺序表)中
	sl_push_back(con, info);
	printf("联系人添加成功!\n");
}

int find_by_name(contact* con, char name[])
{
	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->arr[i].name, name))
		{
			//找到了
			return i;
		}
	}
	return -1;
}

//通讯录删除数据
void contact_delete(contact* con)
{
	//前提是要删除的这个联系人存在
	char name[NAME_MAX];
	printf("请输入您想删除的联系人姓名:\n");
	scanf("%s", name);
	int ret = find_by_name(con, name);
	if (ret < 0)
	{
		printf("联系人不存在!\n");
		//直接返回
		return;
	}
	
	//删除指定位置的数据
	sl_erase(con, ret);
	printf("删除成功!\n");
}

//通讯录数据展示
void contact_show(contact* con)
{
	//打印表头
	printf("%2s %8s %8s %8s %8s\n", "姓名", "性别", "年龄", "电话", "地址");
	printf("———      ———      ———      ———      ———\n");
	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		printf("%2s %7s %7d %9s %9s\n", con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr);
	}
}

//通讯录修改
void contact_modify(contact* con)
{
	//前提是要修改的联系人存在
	char name[NAME_MAX];
	printf("请输入要修改的联系人姓名:\n");
	scanf("%s", name);
	int ret = find_by_name(con, name);
	if (ret < 0)
	{
		printf("联系人不存在!\n");
		return;
	}

	//修改指定位置的数据
	printf("请输入新的姓名:\n");
	scanf("%s", con->arr[ret].name);
	printf("请输入新的性别:\n");
	scanf("%s", con->arr[ret].gender);
	printf("请输入新的年龄:\n");
	scanf("%d", &con->arr[ret].age);
	printf("请输入新的电话:\n");
	scanf("%s", con->arr[ret].tel);
	printf("请输入新的地址:\n");
	scanf("%s", con->arr[ret].addr);

	printf("修改成功!\n");
}

//通讯录查找
void contact_find(contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人姓名:\n");
	scanf("%s", name);
	int ret = find_by_name(con, name);
	if (ret < 0)
	{
		printf("您要查找的联系人不存在!\n");
		return;
	}
	printf("%2s %8s %8s %8s %8s\n", "姓名", "性别", "年龄", "电话", "地址");
	printf("———      ———      ———      ———      ———\n");
	printf("%2s %7s %7d %9s %9s\n", con->arr[ret].name,
		con->arr[ret].gender,
		con->arr[ret].age,
		con->arr[ret].tel,
		con->arr[ret].addr);
}

test.c:

#define  _CRT_SECURE_NO_WARNINGS

#include "seqlist.h"

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

int main()
{
	int input = 0;
	contact con;
	contact_init(&con);
	do
	{
		menu();
		printf("请选择您的操作:");
		scanf("%d", &input);
		switch (input)
		{
		case EXIT:
			printf("退出通讯录!\n");
			break;
		case ADD:
			contact_add(&con);
			break;
		case DELETE:
			contact_delete(&con);
			break;
		case MODIFY:
			contact_modify(&con);
			break;
		case FIND:
			contact_find(&con);
			break;
		case SHOW:
			contact_show(&con);
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}
	} while (input);

	//销毁通讯录
	contact_destroy(&con);

	return 0;
}

总结

  • 通讯录其实就是顺序表,只是上文的顺序表存储的是整型数据,而本文的顺序表存储的结构体类型数据而已
  • 在本篇文章中我们更多的是对保存联系人信息的结构体类型进行相应的操作,通讯录实际上就是顺序表,而顺序表的相关操作是我们已经实现好了的,所以我们只需要拿来用就可以了
  • 通讯录就像是在顺序表的外面又包装了一层其他的操作,使其完成对联系人信息的增删查改操作

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

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

相关文章

对比学习

对比学习基本概念 对比学习通过对比数据对的“相似”或“不同”以获取数据的高阶信息。 由同一张原始图片扩增而来的两张新的图片&#xff0c;叫做Positive Pairs。将这两张图片送入深度学习模型中&#xff0c;我们希望深度学习模型学习到这两个图像是相似的。 由不同原始图…

【尚庭公寓SpringBoot + Vue 项目实战】移动端找房功能(二十一)

【尚庭公寓SpringBoot Vue 项目实战】移动端找房功能&#xff08;二十一&#xff09; 文章目录 【尚庭公寓SpringBoot Vue 项目实战】移动端找房功能&#xff08;二十一&#xff09;1、业务介绍2、接口开发2.1、地区信息2.2、获取全部支付方式列表2.3、房间信息2.2.1. 根据条…

SpringCloud中Eureka和Nacos的区别和各自的优点

Eureka注册中心 Eureka作为一个注册中心&#xff0c;服务提供者把服务注册到注册中心&#xff0c;服务消费者去注册中心拉取信息&#xff0c; 然后通过负载均衡得到对应的服务器去访问。 服务提供者每隔30s向注册中心发送请求&#xff0c;报告自己的状态&#xff0c;当超过一定…

【网络安全的神秘世界】关于Linux中一些好玩的字符游戏

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 佛祖保佑 把 motd 通过xtp拖到Linux中 liyangUbuntu2204:~$ cp motd /etc/motd #一定要放在etc下 liyangUbuntu2204:~$ exi…

windows设置开机启动项

将文件放到下面路径即可实现每次开机启动 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup

数据分析-相关性

0、提高数据样本质量 首先是确保数据采集的准确性与可靠性&#xff0c;也就是如何降低数据误差 系统误差是由测量工具不精确和测量方法选择不当造成的。这类误差我们可以通过校准工具或者选择更合适的测量方法来消除&#xff1b;随机误差是由环境因素等外部不可控原因导致的&…

RStudio Desktop 安装

RStudio 下载 macOS 安装 RStudio Desktop 打开报错 R not found Could not locate an R installation on the system.安装R https://cloud.r-project.org/bin/macosx/安装 R-4.4.1-arm64.pkg 成功打开 参考 RStudio 桌面版安装R

React的Redux的状态管理

步骤 1.创建新项目 npx create-react-app react-redux 2.安装配套工具 npm i reduxjs/toolkit react-redux 3.启动项目 npm run start 4.在src目录下创建store文件夹 5.在store文件夹下创建modules文件夹 6.在store文件夹里创建index.js文件 7.在counterStore.js文件…

Redis的实战常用一、验证码登录(解决session共享问题)(思路、意识)

一、基于session实现登录功能 第一步&#xff1a;发送验证码&#xff1a; 用户在提交手机号后&#xff0c;会校验手机号是否合法&#xff1a; 如果不合法&#xff0c;则要求用户重新输入手机号如果手机号合法&#xff0c;后台此时生成对应的验证码&#xff0c;同时将验证码进行…

Vue81-独享路由守卫

一、 独享路由守卫的定义 当只有某个特定的路由需要做校验的时候&#xff0c;可以在改路由组件规则的地方单独配置独属于改组件的路由守卫。 二、示例 1、需求 系统只在进入新闻路由页面的时候做校验。 2、代码实现 注意&#xff1a; 独享路由守卫&#xff0c;只有前置路由守…

C语言入门系列:数据类型转换

文章目录 一&#xff0c;自动类型转换1&#xff0c;赋值运算1.1&#xff0c;浮点数赋值给整型变量-不安全1.2&#xff0c;整数赋值给浮点数变量-安全1.3&#xff0c;窄类型赋值给宽类型-安全1.4&#xff0c;宽类型赋值给窄类型-不安全 2&#xff0c;混合类型的运算2.1&#xff…

Kotlin 中的内联函数

1 inline 内联函数&#xff1a;消除 Lambda 带来的运行时开销。 举例来说&#xff1a; fun main() {val num1 100val num2 80val result num1AndNum2(num1, num2) { n1, n2 ->n1 n2} }fun num1AndNum2(num1: Int, num2: Int, operation: (Int, Int) -> Int): Int …

【自撰写】【国际象棋入门】第8课 国际象棋残局基础

第8课 国际象棋残局基础 一、残局的特点 残局是棋局的最后&#xff08;收尾&#xff09;阶段&#xff0c;虽然此时棋盘上的子力已经所剩无几&#xff0c;但依照不同的局面分类&#xff0c;残局中存在着许多有意思的变化&#xff0c;初始局面中的细小变化也可能引发到截然不同…

Redis源码学习:ziplist的数据结构和连锁更新问题

ziplist ziplist 是 Redis 中一种紧凑型的列表结构&#xff0c;专门用来存储元素数量少且每个元素较小的数据。它是一个双端链表&#xff0c; 可以在任意一端进行压入/弹出操作&#xff0c;并且该操作的时间复杂度为O(1)。 ziplist数据结构 <zlbytes><zltail>&l…

期货交易豆粕品种详细分析

文章目录 1、豆粕期货标准&#xff08;2024年6月22号数据&#xff09;2、豆粕是什么3、豆粕1、5、9合约区别4、影响豆粕的价格因素1、大豆的供应情况。2、豆粕的季节性3、油粕比&#xff08;豆油和豆粕的价格关系 &#xff09; 5、美国大豆的生产/库存炒作6、豆粕双方&#xff…

Linux中tar压缩与解压缩

TAR是Unix/Linux中常用的归档工具&#xff0c;它可以对文件或目录进行打包但不压缩&#xff0c;或者配合其他工具进行压缩。 压缩文件或目录 以下是一些基本的tar压缩命令&#xff1a; 1.压缩单个文件&#xff1a; tar -cvf archive.tar file1 2.压缩多个文件&#xff1a; t…

微软Edge浏览器全解析

微软Edge浏览器全解析(一) 解决浏览器的主页被篡改后无法通过浏览器的自带设置来恢复的问题 相信各位都有发现新买的联想电脑浏览器的主页设置不太满意,但从浏览器自带的设置上又无法解决此问题,网上找了许多方法都无济于事,特别对有着强迫症的小伙伴们更是一种煎熬。 通…

cocos 如何使用九宫格图片,以及在微信小程序上失效。

1.在图片下方&#xff0c;点击edit。 2.拖动线条&#xff0c;使四角不被拉伸。 3.使用。 其他 在微信小程序上失效&#xff0c;需要将packable合图功能取消掉。

26.2 Django简介

1. Python三大主流框架 根据当前的信息和流行度, Python的三大框架可以归纳为Django, Flask和FastAPI, 以下是对它们的清晰分点表示和归纳:* 1. Django: 一个高级的Python Web框架, 以快速开发和实用简洁的设计出名.它遵循MVC设计模式(但更倾向于MTV模式), 并提供了许多内置的…

实施高效冷却技术:确保滚珠丝杆稳定运行!

滚珠丝杆在运行过程中&#xff0c;由于摩擦、惯性力等因素&#xff0c;会产生一定的热量&#xff0c;当热量无法及时散发时&#xff0c;滚珠丝杆的温度就会升高&#xff0c;会直接影响滚珠丝杆的精度和稳定性&#xff0c;从而影响最终的产品质量。为了让滚珠丝杆保持应有的精度…