基于顺序表实现的可存储性通讯录!!!

news2024/11/26 18:26:48

基于顺序表实现的通讯录

    • 通讯录的基本功能
  • 顺序表
    • 顺序表的部分变量修改
      • 修改处一
      • 修改处二
      • 修改处三
  • 头文件 Contact.h
    • 通讯录自定义结构体
  • 功能实现 源文件 Contact.c
      • 读取文件中联系人的信息 void ContactReadFile(contact* pcon)
      • 保存到文件 void ContactSave(contact* pcon)
    • 测试文件的保存与读取
      • 初始化 void ContactInit(contact* pcon)
      • 销毁当前联系人信息 void ContactDestroy(contact* pcon)
      • 添加联系人 void ContactAdd(contact* pcon)
      • 删除联系人 void ContactDel(contact* pcon)
      • 展示单个人物信息 void ContactSpecifyShow(contact* pcon, unsigned int pos)
      • 展示所有联系人信息 void ContactShow(contact* pcon)
    • 测试添加与删除联系人
      • 查找联系人 void ContactFind(contact* pcon)
      • 更改通讯录信息 void ContactChange(contact* pcon)
    • 测试查找与更改联系人信息
  • 逻辑实现 源文件 test.c
      • 界面菜单 void menu(void)
      • 主体逻辑 void test_contact(void)
  • 结语
  • 源代码
    • Contact.c
    • test.c
    • SeqList.h
    • SeqList.h

通讯录的基本功能

通讯录是用来存储联系人的基本信息,同时也具备对联系人基本信息的添加,删除,修改,查询,显示信息的功能,可以辅助使用者在日常生活中的信息记忆等等。
而存储的信息我们也可以根据自己的需求来设计,这里我们就拿联系人的基本信息:姓名,电话号码,爱好,因她而存在的故事 来举例。

顺序表

这里我们要使用上一期所讲到的顺列表来辅助实现,(不懂的友友们可以先看看上一期顺序表的实现)链接:顺序表的实现。
注意:一定要了解上期顺序表的实现,因为本期通讯录是基于上期顺序表所实现的。

顺序表的部分变量修改

因为通讯录是使用结构体类型,而我们上一期所用到的是 整型变量 所测试的,所以我们在这里要进行部分变量的修改,修改如下:

修改处一

//SeqList.h
#define SLDataType CInfo
bool SLFind(SL* ps, char* x);
int SLFindPos(SL* ps, char* x);

这里将之前的int改为CInfoCInfo是后续我们要实现的结构体,并将SLFind函数与SLFindPos函数 的第二个参数的变量改为char*类型的变量,因为我们通讯录使用结构体为数组元素单位,后续也要用char*类型来存储名字,所以需要改变。

修改处二

//SeqList.c

需要修改的两个函数如下:
在这里插入图片描述
在查找名字的时候,我们传的是字符串指针,需要断言,并且利用strcmp(str1,str2)库函数来比较,两个字符串是否相同,相同则返回0,不同则返回非0

修改处三

//SeqList.c

如下图:
在这里插入图片描述
之前用到的打印顺序表元素的函数现阶段也不适用于结构体,所以要注释掉,之后我们会重新编写通讯录的打印函数。

这也是为了后续查找联系人做准备

头文件 Contact.h

#pragma once

#define NAME_MAX 20
#define PHONE_NUMBER_MAX 30
#define HOBBY_MAX 500
#define STORY_MAX 3000

typedef struct ContactInfo
{
	char name[NAME_MAX];
	char Phone_number[PHONE_NUMBER_MAX];
	char hobby[HOBBY_MAX];
	char Story[STORY_MAX];
}CInfo;

typedef struct SeqList contact;

void ContactReadFile(contact* pcon);//读取文件中联系人的信息

void ContactInit(contact* pcon);//初始化

void ContactDestroy(contact* pcon);//销毁

void ContactShow(contact* pcon);//展示所有联系人信息

void ContactAdd(contact* pcon);//添加联系人

void ContactDel(contact* pcon);//删除联系人

void ContactFind(contact* pcon);//查找联系人

void ContactSpecifyShow(contact* pcon, unsigned int pos);//展示单个人物信息

void ContactSave(contact* pcon);//保存到文件

void ContactChange(contact* pcon);//更改通讯录信息


因为这里要实现的是通讯录,所以我们需要的顺列表的结构体重命名:typedef struct SeqList contact; ,这是因为修改后写成Contact更符合整体风格也更方便阅读

通讯录自定义结构体

#define NAME_MAX 20
#define PHONE_NUMBER_MAX 30
#define HOBBY_MAX 500
#define STORY_MAX 3000

typedef struct ContactInfo
{
	char name[NAME_MAX];
	char Phone_number[PHONE_NUMBER_MAX];
	char hobby[HOBBY_MAX];
	char Story[STORY_MAX];
}CInfo;

为了满足多样化的输入,我这里使用都是字符类型的数组,其依次表示:姓名,电话号码,爱好,因她而存在的故事 ,这里数组的空间大小我们也用#define 宏定义修改方便后续修改。

功能实现 源文件 Contact.c

读取文件中联系人的信息 void ContactReadFile(contact* pcon)

void ContactReadFile(contact* pcon)
{
	CInfo s = { 0 };
	FILE* pf = fopen("Contact.txt", "r");
	if (pf == NULL)
	{
		FILE* pw = fopen("Contact.txt", "w+");
		assert(pw);
		fprintf(pw, "%d\n", 0);
		fclose(pw);
		pw = NULL;
		pf = fopen("Contact.txt", "r");
	}
	
	int i = 0;
	fscanf(pf, "%d", &i);
	while (i--)
	{
		fscanf(pf, "%s %s %s %s", &(s.name), &(s.Phone_number), &(s.hobby), &(s.Story));
		SLPushBack(pcon, s);
	}
	fclose(pf);
	pf = NULL;
}
	FILE* pf = fopen("Contact.txt", "r");

以只读模式创建一个文件指针来读取"Contact.txt",当然在第一次使用的时候,我们的程序文件夹在电脑磁盘中是没有这个文件的,所以fopen会返回一个空指针NULL,所以我们要对pf进行一个判断,若pf为空,我们就要创建一个文件指针pw用"w+"读写模式创建一个文本文件,然后再用pf重新读取。

目前,我们已经成功打开了**“Contact.txt”,我们现在要开始读取文件,如何读取文件呢?这里我们使用了fscanf()函数来进行读取,每次同时读取联系人的名字、电话号、爱好,故事**,再利用while循环来限制读取次数。

那么这个限制次数是多少呢?我们在第一次创建文件时,细节的输入了一个0,这就说明了这个文件中并没有一个联系人的数据,但是如果说我们不是第一次使用,那限制次数又该如何计算呢?

	int i = 0;
	fscanf(pf, "%d", &i);

每当我们进入while循环中,限制次数就是我们在文件第一行读取到的数字,而保存这个数的任务,这就要看我们的下一个函数了。

保存到文件 void ContactSave(contact* pcon)

void ContactSave(contact* pcon)
{
	FILE* pw = fopen("Contact.txt", "w");
	assert(pw);
	fprintf(pw, "%d\n", pcon->size);
	for (int i = 0; i < pcon->size; i++)
	{
		fprintf(pw, "%s\n%s\n%s\n%s\n",
			pcon->arr[i].name, pcon->arr[i].Phone_number,
			pcon->arr[i].hobby, pcon->arr[i].Story);
	}
	fclose(pw);
	pw = NULL;
}
	fprintf(pw, "%d\n", pcon->size);

在保存文件时,我们第一行保存通讯录的有效联系人个数,这也是方便ContactSave函数保存。

	fprintf(pw, "%s\n%s\n%s\n%s\n",
		pcon->arr[i].name, pcon->arr[i].Phone_number,
		pcon->arr[i].hobby, pcon->arr[i].Story);

利用for循环将数位联系人的信息保存在文件中,然后再关闭文件即可。

测试文件的保存与读取

目前,我们存放程序的文件夹是没有"Contact.txt"文本文件的,下面让我们运行来看一下吧。
在这里插入图片描述
我们可以看到在文件夹中多出了一个"Contact.txt"文本文件,并且通过文件预览我们也可看到程序成功将信息保存在了文本中,程序的返回值也为0,所以可以说明代码没问题
在这里插入图片描述

初始化 void ContactInit(contact* pcon)

void ContactInit(contact* pcon)
{
	SLInit(pcon);
	ContactReadFile(pcon);
}

基于以上代码,这里通讯录初始化的实现,只要先调用SLInit(pcon)函数让顺序表初始化,再调用ContactReadFile(pcon)函数读取磁盘中所存储文件即可。

销毁当前联系人信息 void ContactDestroy(contact* pcon)

void ContactDestroy(contact* pcon)
{
	SLDestroy(pcon);
}

同理,销毁当前联系人信息就相当于销毁顺序表。

添加联系人 void ContactAdd(contact* pcon)

void ContactAdd(contact* pcon)
{
	CInfo info;
	printf("请输入姓名:");
	scanf("%s", info.name);
	printf("请输入电话号码:");
	scanf("%s", &info.Phone_number);
	printf("请输入爱好:");
	scanf("%s", info.hobby);
	printf("请输入与他一起的趣事:");
	scanf("%s", info.Story);

	SLPushBack(pcon, info);
}

先创建一个临时变量info,通过scanf函数来输入数据,再将info尾插到顺序表即可实现。

删除联系人 void ContactDel(contact* pcon)

void ContactDel(contact* pcon)
{
	assert(pcon);
	printf("输入你要删除的联系人:");
	char x[NAME_MAX] = { 0 };
	scanf("%s", x);
	int ret = SLFindPos(pcon, x);
	if (ret >= 0)
	{
		SLErase(pcon, ret);
		printf("删除成功!\n");
	}
	else
	{
		printf("不存在该联系人\n");
	}
}

先利用scanf函数输入联系人姓名的信息x,再利用顺序表中的SLFindPos(pcon, x)函数来查找姓名的位置,若返回大于0的值说明x存在,此时就用SLErase(pcon, ret)函数再顺序表中进行删除;若为-1,这说明该联系人x根本不存在。

展示单个人物信息 void ContactSpecifyShow(contact* pcon, unsigned int pos)

void ContactSpecifyShow(contact* pcon, unsigned int pos)
{
	printf("\n姓名:%s\n电话号码:%s\n爱好:%s\nThe story that exists because of her:\n%s\n",
		pcon->arr[pos].name,
		pcon->arr[pos].Phone_number,
		pcon->arr[pos].hobby,
		pcon->arr[pos].Story
	);
}

通过传入顺序表的地址与数组下标来确定联系人的位置,再依次打印数据即可。
PS:在展示联系人与使用者所产生的故事的时候,考虑到字数可能较多影响美观,所以这里在he story that exists because of her:后面进行了换行。

展示所有联系人信息 void ContactShow(contact* pcon)

void ContactShow(contact* pcon)
{
	for (int i = 0; i < pcon->size; i++)
	{
		ContactSpecifyShow(pcon, i);
	}
}

利用for循环遍历顺序表利用ContactSpecifyShow(pcon, i)函数进行逐个打印。

测试添加与删除联系人

#include"SeqList.h"
//测试添加与删除联系人
int main() 
{
	contact con;
	ContactInit(&con);

	printf("输入_1:\n");
	ContactAdd(&con);

	printf("\n输入_2:\n");
	ContactAdd(&con);
	ContactShow(&con);

	printf("\n删除_1\n");
	ContactDel(&con);
	ContactShow(&con);

	ContactDestroy(&con);
	return 0;
}

(PS:为了更清晰的表达本次实验,这里删除了上一次测试所保留的"Contact.txt"文件)
先进行两次输入,然后展示通讯录,再删除原神,再展示通讯录。运行结果如下:
请添加图片描述

查找联系人 void ContactFind(contact* pcon)

void ContactFind(contact* pcon)
{
	assert(pcon);
	printf("输入你要查找的联系人:");
	char x[NAME_MAX] = { 0 };
	scanf("%s", x);
	int ret = SLFindPos(pcon, x);
	if (ret >= 0)
	{
		ContactSpecifyShow(pcon, ret);
	}
	else
	{
		printf("不存在该联系人\n");
	}
}

这里也是基于顺序表,先判断输入的名字x是否存在,存在则单独打印该联系人信息,反之告知不存在。

更改通讯录信息 void ContactChange(contact* pcon)

void ContactChange(contact* pcon)
{
	char str[NAME_MAX] = { 0 };
	printf("输入你要更改的该联系人:");

	scanf("%s", str);
	int ret = SLFindPos(pcon , str);
	if (ret < 0)
	{
		printf("不存在该联系人");
		return 0;
	}

	CInfo info;
	printf("请输入更正后的姓名:");
	scanf("%s", info.name);
	printf("请输入更正后的电话号码:");
	scanf("%s", &info.Phone_number);
	printf("请输入更正后的爱好:");
	scanf("%s", info.hobby);
	printf("请输入更正后的故事:");
	scanf("%s", info.Story);

	SLErase(pcon, ret);
	SLInsert(pcon, ret, info);

}

基于顺序表SLFindPos(pcon , str)函数,先判断要更改人的姓名,是否存在于通讯录,若存在,则让用户输入修改信息,然后先调用SLErase(pcon, ret)函数将该位置的原数据删除,再调用SLInsert(pcon, ret, info)函数对该位置进行添加;反之告知不存在联系人并退出函数。

测试查找与更改联系人信息

先添加三个联系人a,b,c ,再查找已存在的a与·不存在的d,再更改联系人ad,再查找ad,根据逻辑程序运行结果符合预期。
请添加图片描述

逻辑实现 源文件 test.c

界面菜单 void menu(void)

void menu()
{
	printf("+-------------------------------------------------------+\n");
	printf("|         欢迎来到月下的依靠-----志昂的通讯录           |\n");
	printf("|                  请选择你的操作:                      |\n");
	printf("|          1.ContactInit    初始化备忘录                |\n");
	printf("|          2.ContactAdd     添加联系人信息              |\n");
	printf("|          3.ContactDel     删除联系人信息              |\n");
	printf("|          4.ContactShow    展示联系人信息              |\n");
	printf("|          5.ContactFind    查找联系人信息              |\n");
	printf("|          6.ContactSave    保存至文件中                |\n");
	printf("|          7.ContactChange  更改联系人信息              |\n");
	printf("|          8.ContactDestroy 销毁当前联系人信息          |\n");
	printf("|          9.ClearScreen    清除屏幕                    |\n");
	printf("|          0.CloseProgram   退出程序                    |\n");
	printf("+-------------------------------------------------------+\n");
}

这里的菜单只要表达的内容可以让使用者知道如何操作即可。

主体逻辑 void test_contact(void)

void test_contact()
{
	contact con;
	ContactInit(&con);
	
	void (*p[9])(contact * pcon) = { 0,ContactInit, ContactAdd ,
		ContactDel, ContactShow ,ContactFind, ContactSave, 
		ContactChange ,ContactDestroy};
	menu();
	int choose = 0;
	printf("请输入指令:");
	while (scanf("%d", &choose), choose != 0)
	{

		switch (choose)
		{
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
			(*p[choose])(&con);
			break;
		case 9:
			system("cls");
			menu();
			break;
		default:
			printf("请正确输入!!!!\n");
			break;
		}
		printf("请输入指令:");
	}

	ContactDestroy(&con);
}
	void (*p[9])(contact * pcon) = { 0,ContactInit, ContactAdd ,
    ContactDel, ContactShow ,ContactFind, ContactSave, 	ContactChange ,ContactDestroy};

利用函数指针数组存放函数指针,使得输入的数字可以轻松调用函数地址来使用。
当输入值为1~8时,进入到函数指针数组进行调用;
当输入9就利用system()调用控制台指令"cls"来清空屏幕,并重新打印菜单;
当输入为0时,break跳出循环并销毁顺序表所存储的通讯录;
否则就要求使用者重新输入。

结语

到此基于顺序表和文件操作所实现的通讯录就实现了,本期的内容到这里就全部结束了,谢谢大家的观看。
那么,喜欢请多多关注吧。

请添加图片描述

画师:.com
投稿时间:2023年02月03日23:01
作品lD: 105059867
画师ID: 3889453 

源代码

所有源代码如下:

Contact.c

#include"SeqList.h"

void ContactReadFile(contact* pcon)
{
	CInfo s = { 0 };

	FILE* pf = fopen("Contact.txt", "r");

	if (pf == NULL)
	{
		FILE* pw = fopen("Contact.txt", "w+");
		assert(pw);
		fprintf(pw, "%d\n", 0);
		fclose(pw);
		pw = NULL;
		pf = fopen("Contact.txt", "r");
	}

	//读文件
	int i = 0;
	fscanf(pf, "%d", &i);
	while (i--)
	{
		fscanf(pf, "%s %s %s %s", &(s.name), &(s.Phone_number), &(s.hobby), &(s.Story));
		SLPushBack(pcon, s);
	}

	fclose(pf);
	pf = NULL;

}

void ContactSpecifyShow(contact* pcon, unsigned int pos)
{
	printf("\n姓名:%s\n电话号码:%s\n爱好:%s\nThe story that exists because of her:\n%s\n",
		pcon->arr[pos].name,
		pcon->arr[pos].Phone_number,
		pcon->arr[pos].hobby,
		pcon->arr[pos].Story
	);
}

void ContactInit(contact* pcon)
{
	SLInit(pcon);
	ContactReadFile(pcon);
}

void ContactDestroy(contact* pcon)
{
	SLDestroy(pcon);
}

void ContactAdd(contact* pcon)
{
	CInfo info;
	printf("请输入姓名:");
	scanf("%s", info.name);
	printf("请输入电话号码:");
	scanf("%s", &info.Phone_number);
	printf("请输入爱好:");
	scanf("%s", info.hobby);
	printf("请输入与他一起的趣事:");
	scanf("%s", info.Story);

	SLPushBack(pcon, info);
}

void ContactShow(contact* pcon)
{
	for (int i = 0; i < pcon->size; i++)
	{
		ContactSpecifyShow(pcon, i);
	}
}


void ContactFind(contact* pcon)
{
	assert(pcon);
	printf("输入你要查找的联系人:");
	char x[NAME_MAX] = { 0 };
	scanf("%s", x);
	int ret = SLFindPos(pcon, x);
	if (ret >= 0)
	{
		ContactSpecifyShow(pcon, ret);
	}
	else
	{
		printf("不存在该联系人\n");
	}
}

void ContactDel(contact* pcon)
{
	assert(pcon);
	printf("输入你要删除的联系人:");
	char x[NAME_MAX] = { 0 };
	scanf("%s", x);
	int ret = SLFindPos(pcon, x);
	if (ret >= 0)
	{
		SLErase(pcon, ret);
		printf("删除成功!\n");
	}
	else
	{
		printf("不存在该联系人\n");
	}
}

void ContactSave(contact* pcon)
{


	FILE* pw = fopen("Contact.txt", "w");
	assert(pw);
	fprintf(pw, "%d\n", pcon->size);
	for (int i = 0; i < pcon->size; i++)
	{
		fprintf(pw, "%s\n%s\n%s\n%s\n",
			pcon->arr[i].name, pcon->arr[i].Phone_number,
			pcon->arr[i].hobby, pcon->arr[i].Story);
	}
	fclose(pw);
	pw = NULL;

}


void ContactChange(contact* pcon)
{
	char str[NAME_MAX] = { 0 };
	printf("输入你要更改的该联系人:");

	scanf("%s", str);
	int ret = SLFindPos(pcon , str);
	if (ret < 0)
	{
		printf("不存在该联系人");
		return 0;
	}

	CInfo info;
	printf("请输入更正后的姓名:");
	scanf("%s", info.name);
	printf("请输入更正后的电话号码:");
	scanf("%s", &info.Phone_number);
	printf("请输入更正后的爱好:");
	scanf("%s", info.hobby);
	printf("请输入更正后的故事:");
	scanf("%s", info.Story);

	SLErase(pcon, ret);
	SLInsert(pcon, ret, info);
}

test.c

#include"SeqList.h"

void menu()
{
	printf("+-------------------------------------------------------+\n");
	printf("|         欢迎来到月下的依靠-----志昂的通讯录           |\n");
	printf("|                  请选择你的操作:                      |\n");
	printf("|          1.ContactInit    初始化备忘录                |\n");
	printf("|          2.ContactAdd     添加联系人信息              |\n");
	printf("|          3.ContactDel     删除联系人信息              |\n");
	printf("|          4.ContactShow    展示联系人信息              |\n");
	printf("|          5.ContactFind    查找联系人信息              |\n");
	printf("|          6.ContactSave    保存至文件中                |\n");
	printf("|          7.ContactChange  更改联系人信息              |\n");
	printf("|          8.ContactDestroy 销毁当前联系人信息          |\n");
	printf("|          9.ClearScreen    清除屏幕                    |\n");
	printf("|          0.CloseProgram   退出程序                    |\n");
	printf("+-------------------------------------------------------+\n");
}

void test_contact()
{
	contact con;
	ContactInit(&con);
	
	void (*p[9])(contact * pcon) = { 0,ContactInit, ContactAdd ,
		ContactDel, ContactShow ,ContactFind, ContactSave, 
		ContactChange ,ContactDestroy};
	menu();
	int choose = 0;
	printf("请输入指令:");
	while (scanf("%d", &choose), choose != 0)
	{

		switch (choose)
		{
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
			(*p[choose])(&con);
			break;
		case 9:
			system("cls");
			menu();
			break;
		default:
			printf("请正确输入!!!!\n");
			break;
		}
		printf("请输入指令:");
	}

	ContactDestroy(&con);
}

int main()
{

	test_contact();
	//ContactReadFile();
	//test_1();
	return 0;
}

SeqList.h

#include"SeqList.h"

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

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

void SLCheckCapacity(SL* ps)
{
	if (ps->capacity == ps->size)
	{
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
		assert(tmp);
		ps->arr = tmp;
		tmp = NULL;
		ps->capacity = newcapacity;
	}
}

void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	ps->arr[ps->size++] = x;

}

void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	int i = 0;
	for (i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->size++;
	ps->arr[0] = x;
}

//void SLPrint(SL* ps)
//{
//	int i = 0;
//	for (i = 0; i < ps->size; i++)
//	{
//		printf("%d ", ps->arr[i]);
//	}
//	printf("\n");
//}



void SLPopBack(SL* ps)
{
	assert(ps);
	assert(!SLIsEmpty(ps));
	ps->size--;
}

void SLPopFront(SL* ps)
{
	assert(ps);
	assert(!SLIsEmpty(ps));
	int i = 0;
	for (i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

bool SLIsEmpty(SL* ps)
{
	assert(ps);
	return (ps->size == 0);
}

void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	if (pos < 0 || pos > ps->size)
	{
		printf("输入错误!!!");
		return;
	}

	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;

	ps->size++;
}

void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(!SLIsEmpty(ps));
	for (int i = pos; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;

}

bool SLFind(SL* ps, char* x)
{
	assert(ps&&x);
	for (int i = 0; i < ps->size; i++)
	{
		if(0 == strcmp(ps->arr[i].name,x))
			return true;
	}
	return false;
}

int SLFindPos(SL* ps, char* x)
{
	assert(ps&&x);
	for (int i = 0; i < ps->size; i++)
	{
		if(0 == strcmp(ps->arr[i].name, x))
			return i;
	}
	return -1;
}

void SLRevise(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	if (pos >= ps->size && ps < 0)
	{
		printf("输入错误,无法修改\n");
		return;
	}
	ps->arr[pos] = x;
}

SeqList.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1

#include"Contact.h"

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

#define SLDataType CInfo

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

void SLInit(SL* ps);
void SLDestroy(SL* ps);

void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
void SLPopBack(SL* ps);

void SLErase(SL* ps, int pos);
void SLInsert(SL* ps, int pos, SLDataType x);
bool SLFind(SL* ps, char* x);
int SLFindPos(SL* ps, char* x);
void SLRevise(SL* ps, int pos, SLDataType x);

//void SLPrint(SL* ps);
bool SLIsEmpty(SL* ps);

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

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

相关文章

Python:知道什么叫类吗,我这人实在不知道啥叫累。Python类的定义和使用。

前言 在 python 中&#xff0c;对于相同类型的对象进行分类&#xff0c;抽象后&#xff0c;得出共同的特征而形成了类&#xff08;class&#xff09;&#xff0c;面向对象程序设计的关键就是如何合理地定义这些类并且组织多个类之间的关系。 创建类时用变量形式表示对象特征的…

ChinaSoft 论坛巡礼|开源软件供应链论坛

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;由CCF主办&#xff0c;CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办&#xff0c;将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

Python基础之列表、元组和字典

一文拿捏Python基本数据类型“列表、数组和字典” 引言 Python中的 列表(英文叫list) 、 元组(英文叫tuple)和字典&#xff08;dictionary&#xff09; 也是 序列 特性的&#xff0c;它们也是非常常用的数据类型。 1、列表&#xff08;List&#xff09; 01、概述 列表&#…

【黑马程序员】SSM框架——SSM整合

文章目录 前言一、SSM 整合1. SSM 整合思路1.1 Spring 整合 MyBatis配置模型数据层标准开发业务层标准开发测试接口事务处理 1.2 Spring 整合 SpringMVCweb 配置类SpringMVC 配置类基于 Restful 的 Controller 开发 2. SSM 整合具体实现2.1 创建工程2.2 SSM 整合SpringMyBatisS…

forward和完美转发

std::move(value)是独立于值的右值引用&#xff0c;一个右值引用参数作为函数的形参&#xff0c;在函数内部再转发该参数的时候已经变成了一个左值&#xff0c;并不是它原来的类型了。 template<typename T> void forwardValue(T& val) {processValue(value); //…

基于STC12C5A60S2系列1T 8051单片机A/D转换器应用

基于STC12C5A60S2系列1T 8051单片机A/D转换器应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍STC12C5A60S2系列1T 8051单片机A/D转换器介绍STC12C5A60S2系列1T 805…

算法题:870. 优势洗牌

该算法是临时想出来的&#xff0c;Java代码的实现在时间上不占优&#xff0c;之后有时间要优化一下&#xff0c;目前就是给大家提供一下思路。 解题思路&#xff1a;田忌赛马的思想 贪心法。 Step1. 对两个数组进行排序。 Step2. 同时遍历排序后的nums2和nums1&#xff0c;将…

RAM和ROM的区别(详解)

RAM和ROM的区别 RAM&#xff08;随机存取存储器&#xff09;和ROM&#xff08;只读存储器&#xff09;都是计算机中常见的存储器类型&#xff0c;它们在计算机系统中有不同的作用和特性。 RAM&#xff08;随机存取存储器&#xff09;&#xff1a; 作用&#xff1a; 用于临时存储…

鸿蒙LiteOs读源码教程+向LiteOS中添加一个简单的基于线程运行时的短作业优先调度策略

一、鸿蒙Liteos读源码教程 鸿蒙的源码是放在openharmony文件夹下&#xff0c;openharmony下的kernel文件夹存放操作系统内核的相关代码和实现。 内核是操作系统的核心部分&#xff0c;所以像负责&#xff1a;资源管理、任务调度、内存管理、设备驱动、进程通信的源码都可以在…

利用maven的dependency插件将项目依赖从maven仓库中拷贝到一个指定的位置

https://maven.apache.org/plugins/maven-dependency-plugin/copy-dependencies-mojo.html 利用dependency:copy-dependencies可以将项目的依赖从maven仓库中拷贝到一个指定的位置。 使用默认配置拷贝依赖 如果直接执行mvn dependency:copy-dependencies&#xff0c;是将项目…

解决方案中word中分页符的使用

在投标方案中要善于使用“分页符”&#xff0c;尽可能少使用分节符号&#xff0c;没有分页符前&#xff0c;你每次修改你的标书或者文件&#xff0c;增加或者修改内容后。你的格式字段前后都是会发生变化&#xff0c;如何稳定的保证结构呢&#xff0c;那就是分页符的使用&#…

如何提高Python图像表格数据提取的准确率?

Python图像表格数据提取 1、数据来源2、目标图像3、图像文本提取4、图像灰度化与二值化可以提高识别准确率吗1、数据来源 国家统计局:http://www.stats.gov.cn/sj/ 数据来源:国家统计局中国统计年鉴2022年人口数及构成 2、目标图像 数据(部分)如下: 数据形式:http://www…

【触想智能】4U触摸工控机具有哪些优势?

工控机也叫工控主机&#xff0c;和我们常见的普通电脑主机是一样的&#xff0c;都是由CPU、主板、内存、硬盘、电源以及机箱组成的。 工控机有很多分类&#xff0c;有无风扇工控机、嵌入式工控机、上架式工控机、4U触摸工控机等。上架式工控机在市场上是比较受欢迎的&#xff0…

【数据结构】树家族

目录 树的相关术语树家族二叉树霍夫曼树二叉查找树 BST平衡二叉树 AVL红黑树伸展树替罪羊树 B树B树B* 树 当谈到数据结构中的树时&#xff0c;我们通常指的是一种分层的数据结构&#xff0c;它由节点&#xff08;nodes&#xff09;组成&#xff0c;这些节点之间以边&#xff08…

Web自动化测试 —— cookie复用

一、cookie简介 cookie是一些数据&#xff0c;存储于用户电脑的文本文件中 当web服务器想浏览器发送web页面时&#xff0c;在链接关闭后&#xff0c;服务端不会记录用户信息 二、为什么要使用Cookie自动化登录 复用浏览器仍然在每次用例开始都需要人为介入若用例需要经常执行&…

nodejs+vue+python+php在线购票系统的设计与实现-毕业设计

伴随着信息时代的到来&#xff0c;以及不断发展起来的微电子技术&#xff0c;这些都为在线购票带来了很好的发展条件。同时&#xff0c;在线购票的范围不断增大&#xff0c;这就需要有一种既能使用又能使用的、便于使用的、便于使用的系统来对其进行管理。在目前这种大环境下&a…

你渲染的3ds Max效果图为什么这么假?原来问题出在这!

有许多设计新手刚开始做效果图时&#xff0c;常常抱怨自己的作品看起来太假了&#xff0c;但又不知道怎么改。根据我的经验总结&#xff0c;我整理了以下几点可能导致你的3ds Max渲染效果图显得不够真实的原因。 1.三维模型不精致 如果模型细节不够精细&#xff0c;渲染出来的…

QT学习之QT概述

1.1 什么是QT&#xff1f; Qt是一个跨平台的C图形用户界面应用程序框架。 QT特点&#xff1a; 跨平台&#xff0c;几乎支持所有的平台接口简单&#xff0c;容易上手&#xff0c;学习QT框架对学习其他框架有参考意义。一定程度上简化了内存回收机制开发效率高&#xff0c;能够…

【Linux】 ps 命令使用

ps &#xff08;英文全拼&#xff1a;process status&#xff09;命令用于显示当前进程的状态&#xff0c;类似于 windows 的任务管理器。 语法 ps [选项] ps命令 -Linux手册页 著者 ps最初由布兰科兰克斯特撰写<lankestefwi.uva.nl>。迈克尔K约翰逊<johnsonmred…

Proteus仿真--12864LCD显示计算器键盘按键实验(仿真文件+程序)

本文主要介绍基于51单片机的12864LCD液晶显示电话拨号键盘按键实验&#xff08;完整仿真源文件及代码见文末链接&#xff09; 仿真图如下 本设计主要介绍计算器键盘仿真&#xff0c;按键按下后在12864液晶上显示对应按键键值 仿真运行视频 Proteus仿真--12864LCD显示计算器…