Langage C : carnet d'adresses version dynamique (amélioration de la version statique)

insérez la description de l'image ici


L'idée d'implémentation et le code complet de la version statique du carnet d'adresses

1. Orientation à améliorer

Pour les données de gestion, nous effectuons principalement des ajouts, des suppressions, des contrôles et des modifications . Nous souhaitons améliorer la version statique du carnet d'adresses, principalement en ajoutant des directions de données. La suppression, la recherche et la modification n'affecteront pas la taille de l'espace réel, nous n'avons donc pas besoin de le modifier.

1. Structure

La plus grande amélioration en termes de structure est que nous avons ajouté une capacité variable pour enregistrer la taille de l'espace que nous avons ouvert dynamiquement, et les données variables pointent vers l'espace que nous avons ouvert.

typedef struct PeoInfo
{
    
    
	char name[20];
	char sex[5];
	int age;
	char tele[12];
	char adder[20];
}PeoInfo;

//动态版本
typedef struct Contact
{
    
    
	PeoInfo* data;
	int sz;//记录此时已用的大小
	int capacity;//记录通讯录的大小
}Contact;

2. Initialisation

Puisqu'il s'agit de réaliser la version dynamique du carnet d'adresses, la taille de l'espace pointé par les données variables doit être variable, et la fonction de mémoire dynamique doit être utilisée pour ouvrir l'espace. La capacité variable enregistre la taille du espace ouvert à ce moment, et la variable sz = 0 (ici La donnée valide dans le carnet d'adresses est 0).

#define INITSIZE 10

//初始化通讯录
void InitContact(Contact* pc)
{
    
    
	pc->sz = 0;
	pc->capacity = INITSIZE;
	pc->data = (PeoInfo*)malloc(sizeof(PeoInfo) * INITSIZE);
	if (pc->data == NULL)
	{
    
    
		perror("malloc");
		return;
	}
}

3. Augmenter les contacts et vérifier la capacité

L'idée générale de l'ajout de contacts n'a pas changé, mais lorsque sz == capacité (les données effectives sont égales à la taille de l'espace), on ne refuse plus l'opération de l'utilisateur pour ajouter des contacts, mais on étend la capacité de l'espace pour permettre aux utilisateurs pour continuer à fonctionner.
Lors de l'agrandissement de l'espace, n'oubliez pas que la capacité changera également.

//检查容量
bool CheckCapacity(Contact* pc)
{
    
    
	PeoInfo* tmp = realloc(pc->data, sizeof(PeoInfo) * (pc->capacity) * 2);
	if (tmp == NULL)
	{
    
    
		perror("realloc");
		return false;
	}
	pc->data = tmp;
	pc->capacity *= 2;
	return true;
}

//添加联系人
void AddContact(Contact* pc)
{
    
    
	assert(pc);

	if (pc->sz == pc->capacity)
	{
    
    
		if (CheckCapacity(pc) == true)
		{
    
    
			printf("扩容成功\n");
		}
		else
		{
    
    
			printf("扩容失败\n");
			return;
		}
	}

	printf("请输入联系人名字:>");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入联系人性别:>");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入联系人年龄:>");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入联系人电话:>");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入联系人地址:>");
	scanf("%s", pc->data[pc->sz].adder);
	pc->sz += 1;
}

4. Quitter

Lorsque l'utilisateur quitte le carnet d'adresses, nous devons libérer l'espace développé dynamiquement (sinon cela provoquera une fuite de mémoire) et définir nous-mêmes les données sur null. sz et capacité doivent également être définis sur 0.

//退出通讯录
void ExitContact(Contact* pc)
{
    
    
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
}

2. Mise en œuvre du code

//test.c文件

#include "contact.h"


void menu()
{
    
    
	printf("******************************\n");
	printf("**** 1.add     2.del      ****\n");
	printf("**** 3.search  4.modify   ****\n");
	printf("**** 5.show    6.destroy  ****\n");
	printf("**** 7.sort    8.exit     ****\n");
	printf("******************************\n");
}

int main()
{
    
    
	int input = 1;
	Contact con;
	InitContact(&con);
	while (input)
	{
    
    
		menu();
		printf("请输入所选择的标号:>");
		scanf("%d", &input);
		switch (input)
		{
    
    
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case DESTROY:
			DestroyContact(&con);
			break;
		case SORT:
			SortConTact(&con);
			break;
		case EXIT:
			printf("退出通讯录\n");
			break;
		default:
			printf("输入错误,请从新输入\n");
			break;
		}
	}
	return 0;
}

//contact.c 文件

#include "contact.h"

//静态版本
初始化通讯录
//void InitContact(Contact* pc)
//{
    
    
//	pc->sz = 0;
//}


//动态版本
//初始化通讯录
void InitContact(Contact* pc)
{
    
    
	pc->sz = 0;
	pc->capacity = INITSIZE;
	pc->data = (PeoInfo*)malloc(sizeof(PeoInfo) * INITSIZE);
	if (pc->data == NULL)
	{
    
    
		perror("malloc");
		return;
	}
}


//检查容量
bool CheckCapacity(Contact* pc)
{
    
    
	PeoInfo* tmp = realloc(pc->data, sizeof(PeoInfo) * (pc->capacity) * 2);
	if (tmp == NULL)
	{
    
    
		perror("realloc");
		return false;
	}
	pc->data = tmp;
	pc->capacity *= 2;
	return true;
}

//添加联系人
void AddContact(Contact* pc)
{
    
    
	assert(pc);

	if (pc->sz == pc->capacity)
	{
    
    
		if (CheckCapacity(pc) == true)
		{
    
    
			printf("扩容成功\n");
		}
		else
		{
    
    
			printf("扩容失败\n");
			return;
		}
	}

	printf("请输入联系人名字:>");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入联系人性别:>");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入联系人年龄:>");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入联系人电话:>");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入联系人地址:>");
	scanf("%s", pc->data[pc->sz].adder);
	pc->sz += 1;
}



//打印通讯录
void ShowContact(Contact* pc)
{
    
    
	assert(pc);

	printf("%-20s\t%-5s\t%-2s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < pc->sz; i++)
	{
    
    
		printf("%-20s\t%-5s\t%-2d\t%-12s\t%-20s\n"
			, pc->data[i].name
			, pc->data[i].sex
			, pc->data[i].age
			, pc->data[i].tele
			, pc->data[i].adder);
	}
}


//查找名字
bool FindName(Contact* pc, char* name, int* retIndex)
{
    
    
	for (int i = 0; i < pc->sz; i++)
	{
    
    
		if (strcmp(pc->data[i].name, name) == 0)
		{
    
    
			*retIndex = i;
			return true;
		}
	}

	return false;
}


//删除联系人
void DelContact(Contact* pc)
{
    
    
	assert(pc);

	char name[20] = {
    
     0 };
	printf("请输入要删除联系人的名字:>");
	scanf("%s", name);

	int retIndex = 0;
	if (FindName(pc, name, &retIndex) == true)
	{
    
    
		for (int i = retIndex; i < pc->sz - 1; i++)
		{
    
    
			pc->data[i] = pc->data[i + 1];
		}
		pc->sz -= 1;
		printf("删除联系人成功\n");
		return;
	}

	printf("删除联系人失败\n");
	return;
}



//查找联系人
void SearchContact(Contact* pc)
{
    
    
	assert(pc);

	char name[20] = {
    
     0 };
	printf("请输入要查找联系人的名字:>");
	scanf("%s", name);

	int retIndex = 0;
	if (FindName(pc, name, &retIndex) == true)
	{
    
    
		printf("%-20s\t%-5s\t%-2s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");
		printf("%-20s\t%-5s\t%-2d\t%-12s\t%-20s\n"
			, pc->data[retIndex].name
			, pc->data[retIndex].sex
			, pc->data[retIndex].age
			, pc->data[retIndex].tele
			, pc->data[retIndex].adder);
		return;
	}

	printf("查找失败\n");
	return;
}



//销毁通讯录
void DestroyContact(Contact* pc)
{
    
    
	assert(pc);

	pc->sz = 0;
	printf("销毁成功\n");
}


//修改联系人
void ModifyContact(Contact* pc)
{
    
    
	assert(pc);

	char name[20] = {
    
     0 };
	printf("请输入要修改联系人的名字:>");
	scanf("%s", name);

	int retIndex = 0;
	if (FindName(pc, name, &retIndex) == true)
	{
    
    
		printf("请输入联系人名字:>");
		scanf("%s", pc->data[retIndex].name);
		printf("请输入联系人性别:>");
		scanf("%s", pc->data[retIndex].sex);
		printf("请输入联系人年龄:>");
		scanf("%d", &(pc->data[retIndex].age));
		printf("请输入联系人电话:>");
		scanf("%s", pc->data[retIndex].tele);
		printf("请输入联系人地址:>");
		scanf("%s", pc->data[retIndex].adder);

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

	printf("修改失败\n");
	return;
}


//排序通讯录

void Swap(Contact* pc, int left, int right)
{
    
    
	PeoInfo tmp = pc->data[left];
	pc->data[left] = pc->data[right];
	pc->data[right] = tmp;
}

int PivotIndex(Contact* pc, int startIndex, int endIndex)
{
    
    
	PeoInfo tmp = pc->data[startIndex];

	int right = endIndex;
	int left = startIndex;
	while (left < right)
	{
    
    
		while (left < right && strcmp(pc->data[right].name, tmp.name) > 0)
		{
    
    
			right--;
		}

		while (left < right && strcmp(pc->data[left].name, tmp.name) <= 0)
		{
    
    
			left++;
		}

		Swap(pc, left, right);
	}
	pc->data[startIndex] = pc->data[left];
	pc->data[left] = tmp;

	return left;
}

void QuickSort(Contact* pc, int startIndex, int endIndex)
{
    
    
	if (startIndex > endIndex)
	{
    
    
		return;
	}

	int pivot = PivotIndex(pc, startIndex, endIndex);
	QuickSort(pc, startIndex, pivot - 1);
	QuickSort(pc, pivot + 1, endIndex);
}

void SortConTact(Contact* pc)
{
    
    
	assert(pc);

	QuickSort(pc, 0, pc->sz - 1);
	printf("排序成功\n");
}


//退出通讯录
void ExitContact(Contact* pc)
{
    
    
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
}

//contact.h 文件

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1

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

//#define MAXSIZE 100
#define INITSIZE 10


enum {
    
    
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	DESTROY,
	SORT,
};


typedef struct PeoInfo
{
    
    
	char name[20];
	char sex[5];
	int age;
	char tele[12];
	char adder[20];
}PeoInfo;

//静态版本
//typedef struct Contact
//{
    
    
//	PeoInfo data[MAXSIZE];
//	int sz;
//}Contact;

//动态版本
typedef struct Contact
{
    
    
	PeoInfo* data;
	int sz;//记录此时已用的大小
	int capacity;//记录通讯录的大小
}Contact;


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

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

//打印通讯录
void ShowContact(Contact* pc);

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

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

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

//修改联系人
void ModifyContact(Contact* pc);

//排序通讯录
void SortConTact(Contact* pc);

//检查容量
bool CheckCapacity(Contact* pc);

//退出通讯录
void ExitContact(Contact* pc);


Résumer

Ce qui précède est mon implémentation de la version dynamique du carnet d'adresses.

Ma page d'accueil personnelle bienvenue support

insérez la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/li209779/article/details/131934311
conseillé
Classement