C语言实现简易的通讯录【静态内存】

本文介绍了如何使用C语言实现一个静态内存管理的简易通讯录,包括结构体设计、初始化、增删查改等功能。通过菜单选择操作,支持1000个联系人信息,如姓名、性别、年龄、电话和住址。此外,还实现了按名字排序和清空所有联系人等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现目标

  1. 通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
  2. 实现7个功能
    1. 添加联系人信息
    2. 删除指定联系人信息
    3. 查找指定联系人信息
    4. 修改指定联系人信息
    5. 显示所有联系人信息
    6. 清空所有联系人
    7. 以名字排序所有联系人

功能实现

主函数功能选择菜单

既然要实现多种功能,那就得有菜单进行选择,可以利用switch函数进行选择

void meu()
{
	printf("*****************************************************************\n");
	printf("********1、新建联系人                  2、删除联系人*************\n");
	printf("********3、查找联系人                  4、修改联系人*************\n");
	printf("********5、显示所有联系人              6、清空所有联系人*********\n");
	printf("********7、以名字排序所有联系人        0、退出程序***************\n");
	printf("*****************************************************************\n");
}
int main()
{
	int i = 1;
	con pc;
	init(&pc);
	while (i)
	{
		meu();
		printf("请输入你的选择->");
		scanf("%d", &i);
		switch (i)
		{
		case 0:
			printf("exit\n");
			break;
		case 1:
			add(&pc);
			break;
		case 2:
			delete(&pc);
			break;
		case 3:
			seek(&pc);
			break;
		case 4:
			revise(&pc);
			break;
		case 5:
			display(&pc);
			break;
		case 6:
			clear(&pc);
			break;
		case 7:
			sort(&pc);
			break;
		default:
			printf("输入错误\n");
			break;
		}
	}
	return 0;
}

创建结构体类型

每一位联系人中都包含了几个个人信息,所以就得创建新的结构体变量来存储信息
(代码中用到的宏定义在下面头文件代码展示中会有),用宏定义后方便我们以后对代码进行改动

typedef struct people
{
	char name[max_name];//名字
	char sex[max_sex];//性别
	char phone[max_phone];//电话号码
	char home[max_home];//住址
	int age;//年龄
}people;

创建好了结构体联系人类型后,由于通讯录需要存放1000个联系人,所以我们还得创建一个结构体类型

typedef struct con
{
	int count;//联系人总数
	people date[max];
}con;

初始化函数

创建好通讯录后,首先得进行初始化,这里把通讯录里的内容全部初始化为0

void init(con* pc)
{
	assert(pc);
	pc->count = 0;
	//利用库函数对数组里的每一项都初始化
	memset(pc->date, 0, sizeof(pc->date));
}

新增联系人

  1. 判断通讯录人数是否已满

  2. 如果没满,则给通讯录类型中的联系人结构体中的每一项赋值

  3. 通讯录中联系人总数加1

//增加联系人
void add(con* pc)
{
	assert(pc);
	if (pc->count < 1000)
	{
		printf("请输入联系人名字->");
		scanf("%s", pc->date[pc->count].name);
		printf("请输入联系人性别->");
		scanf("%s", pc->date[pc->count].sex);
		printf("请输入联系人年龄->");
		scanf("%d", &(pc->date[pc->count].age));
		printf("请输入联系人电话->");
		scanf("%s", pc->date[pc->count].phone);
		printf("请输入联系人住址->");
		scanf("%s", pc->date[pc->count].home);
		pc->count++;
		printf("添加成功\n");
	}
	else
		printf("通讯录已满\n");
	printf("\n");
}

查找指定联系人下标

因为下面的查找、修改都需要用到这一步,所以我们通过一个函数来实现这一步

//查找某联系人下标函数
int find(char* arr,con* pc)
{
	int i = 0;
	for (i = 0; i < pc->count; i++)
	{
	//比较名字是否一样,如果有一样的则该下标符合目的
		if (strcmp(arr, pc->date[i].name) == 0)
			return i;
	}
	return -1;
}

删除指定联系人

  1. 删除一个联系人首先得先找到这个联系人所在的数组下标

  2. 找到该联系人后怎么样删除,这里用的方法是利用该联系人后面的所有联系人都往前覆盖一位的做法,然后联系人总数减1

  3. 如果没有找到该联系人,则打印输出

//删除联系人
void delete(con* pc)
{
	char arr[20] = { '\0' };
	printf("请输入你要删除的联系人名字->");
	scanf("%s", arr);
	//调用函数查找下标
	int i = find(arr, pc);
	if (i == -1)
		printf("该联系人不存在\n");
	else
	{
		int k = 0;
		//该联系人后面的每一项都往前覆盖一项
		for (k = i; k < pc->count - 1; k++)
			pc->date[k] = pc->date[k + 1];
		//联系人总数减1
		pc->count--;
		printf("删除成功\n");
	}
	printf("\n");
}

查找指定联系人信息

只需要找到该联系人下标后,将该下标的数据全部打印输出出来

//查找联系人
void seek(con* pc)
{
	char arr[20] = { '\0'};
	printf("请输入你要查找的联系人名字->");
	scanf("%s", arr);
	//调用函数查找下标
	int i = find(arr, pc);
	if (i != -1)
		printf("%s\t%s\t%d\t%s\t%s\t\n", pc->date[i].name, pc->date[i].sex, pc->date[i].age
			, pc->date[i].phone, pc->date[i].home);
	else
		printf("没有该联系人\n");
	printf("\n");
}

修改指定联系人

  1. 判断联系人是否存在,如果存在利用通用查找函数找到该联系人下标

  2. 重新输入该联系人全部信息即可

//修改联系人
void revise(con* pc)
{
	char arr[20] = { '\0' };
	printf("请输入你要修改的联系人名字->");
	scanf("%s", arr);
	//调用函数查找下标
	int i = find(arr, pc);
	if (i == -1)
		printf("该联系人不存在\n");
	else
	{
		printf("请输入修改后联系人名字->");
		scanf("%s", pc->date[i].name);
		printf("请输修改后入联系人性别->");
		scanf("%s", pc->date[i].sex);
		printf("请输入修改后联系人年龄->");
		scanf("%d", &(pc->date[i].age));
		printf("请输入修改后联系人电话->");
		scanf("%s", pc->date[i].phone);
		printf("请输入修改后联系人住址->");
		scanf("%s", pc->date[i].home);
		printf("修改成功\n");
	}
	printf("\n");
}

显示所有联系人

  1. 判断通讯录中是否有联系人

  2. 如果有联系人则将联系人的每一项数据打印

//打印所有联系人
void display(const con* pc)
{
	int i = pc->count;
	if(i != 0)
	{
	//当i为0则已经打印出所有联系人信息
		while (i--)
			printf("%s\t%s\t%d\t%s\t%s\t\n", pc->date[i].name, pc->date[i].sex, pc->date[i].age
				, pc->date[i].phone, pc->date[i].home);
	}
	else
		printf("通讯录为空\n");
	printf("\n");
}

清空所有联系人

  1. 先判断通讯录里是否有联系人
  2. 如果有则初始化通讯录即可
//清空联系人
void clear(con* pc)
{
	if (pc->count != 0)
	{
		init(pc);
		printf("清空成功\n");
	}
	else
		printf("通讯录为空\n");
	printf("\n");
}

以名字排序所有联系人

  1. 通过几大排序法按照名字的大小排序即可,这里用冒泡排序实现升序

  2. 比较名字大小,由于名字是字符串即使用strcmp函数实现

//以名字排序所有联系人
void sort(con* pc)
{
	int i = 0, j = 0;
	//按照名字大小用冒泡排序法进行排序
	for (i = 0; i < pc->count - 1; i++)
	{
		for (j = 0; j < pc->count - 1 - i; j++)
		{
			//比较名字大小
			if (strcmp(pc->date[j].name, pc->date[j + 1].name) > 0)
			{
				//两值交换 注意结构体类型要一致
				people temp;
				temp = pc->date[j];
				pc->date[j] = pc->date[j + 1];
				pc->date[j + 1] = temp;
			}
		}
	}
	printf("排序成功\n");
	printf("\n");
}

整体代码

address.h

#pragma once

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

#define max_name 20
#define max_sex 5
#define max_phone 20
#define max_home 40
#define max 1000

typedef struct people
{
	char name[max_name];//名字
	char sex[max_sex];//性别
	char phone[max_phone];//电话号码
	char home[max_home];//住址
	int age;//年龄
}people;

typedef struct con
{
	int count;//联系人总数
	people date[max];
}con;

void init(con* pc);

void add(con* pc);

void display(const con* pc);

int find(char* arr, con* pc);

void seek(con* pc);

void delete(con* pc);

void revise(con* pc);

void clear(con* pc);

void sort(con* pc);

address.c

#include "address.h"

//初始化函数
void init(con* pc)
{
	assert(pc);
	pc->count = 0;
	memset(pc->date, 0, sizeof(pc->date));
}

//增加联系人
void add(con* pc)
{
	assert(pc);
	if (pc->count < 1000)
	{
		printf("请输入联系人名字->");
		scanf("%s", pc->date[pc->count].name);
		printf("请输入联系人性别->");
		scanf("%s", pc->date[pc->count].sex);
		printf("请输入联系人年龄->");
		scanf("%d", &(pc->date[pc->count].age));
		printf("请输入联系人电话->");
		scanf("%s", pc->date[pc->count].phone);
		printf("请输入联系人住址->");
		scanf("%s", pc->date[pc->count].home);
		pc->count++;
		printf("添加成功\n");
	}
	else
		printf("通讯录已满\n");
	printf("\n");
}

//打印所有联系人
void display(const con* pc)
{
	int i = pc->count;
	while (i--)
		printf("%s\t%s\t%d\t%s\t%s\t\n", pc->date[i].name, pc->date[i].sex, pc->date[i].age
			, pc->date[i].phone, pc->date[i].home);
	printf("\n");
}

//查找某联系人下标函数
int find(char* arr,con* pc)
{
	int i = 0;
	for (i = 0; i < pc->count; i++)
	{
		if (strcmp(arr, pc->date[i].name) == 0)
			return i;
	}
	return -1;
}

//查找联系人
void seek(con* pc)
{
	char arr[20] = { '\0'};
	printf("请输入你要查找的联系人名字->");
	scanf("%s", arr);
	int i = find(arr, pc);
	if (i != -1)
		printf("%s\t%s\t%d\t%s\t%s\t\n", pc->date[i].name, pc->date[i].sex, pc->date[i].age
			, pc->date[i].phone, pc->date[i].home);
	else
		printf("没有该联系人\n");
	printf("\n");
}

//删除联系人
void delete(con* pc)
{
	char arr[20] = { '\0' };
	printf("请输入你要删除的联系人名字->");
	scanf("%s", arr);
	int i = find(arr, pc);
	if (i == -1)
		printf("该联系人不存在\n");
	else
	{
		int k = 0;
		for (k = i; k < pc->count - 1; k++)
			pc->date[k] = pc->date[k + 1];
		pc->count--;
		printf("删除成功\n");
	}
	printf("\n");
}

//修改联系人
void revise(con* pc)
{
	char arr[20] = { '\0' };
	printf("请输入你要修改的联系人名字->");
	scanf("%s", arr);
	int i = find(arr, pc);
	if (i == -1)
		printf("该联系人不存在\n");
	else
	{
		printf("请输入修改后联系人名字->");
		scanf("%s", pc->date[i].name);
		printf("请输修改后入联系人性别->");
		scanf("%s", pc->date[i].sex);
		printf("请输入修改后联系人年龄->");
		scanf("%d", &(pc->date[i].age));
		printf("请输入修改后联系人电话->");
		scanf("%s", pc->date[i].phone);
		printf("请输入修改后联系人住址->");
		scanf("%s", pc->date[i].home);
		printf("修改成功\n");
	}
	printf("\n");
}

//清空联系人
void clear(con* pc)
{
	if (pc->count != 0)
	{
		init(pc);
		printf("清空成功\n");
	}
	else
		printf("通讯录为空\n");
	printf("\n");
}

//以名字排序所有联系人
void sort(con* pc)
{
	int i = 0, j = 0;
	//按照名字大小用冒泡排序法进行排序
	for (i = 0; i < pc->count - 1; i++)
	{
		for (j = 0; j < pc->count - 1 - i; j++)
		{
			//比较名字大小
			if (strcmp(pc->date[j].name, pc->date[j + 1].name) > 0)
			{
				//两值交换 注意结构体类型要一致
				people temp;
				temp = pc->date[j];
				pc->date[j] = pc->date[j + 1];
				pc->date[j + 1] = temp;
			}
		}
	}
	printf("排序成功\n");
	printf("\n");
}

main.c

#include "address.h"
//打印菜单
void meu()
{
	printf("*****************************************************************\n");
	printf("********1、新建联系人                  2、删除联系人*************\n");
	printf("********3、查找联系人                  4、修改联系人*************\n");
	printf("********5、显示所有联系人              6、清空所有联系人*********\n");
	printf("********7、以名字排序所有联系人        0、退出程序***************\n");
	printf("*****************************************************************\n");
}
int main()
{
	int i = 1;
	con pc;
	init(&pc);
	while (i)
	{
		meu();
		printf("请输入你的选择->");
		scanf("%d", &i);
		switch (i)
		{
		case 0:
			printf("exit\n");
			break;
		case 1:
			add(&pc);
			break;
		case 2:
			delete(&pc);
			break;
		case 3:
			seek(&pc);
			break;
		case 4:
			revise(&pc);
			break;
		case 5:
			display(&pc);
			break;
		case 6:
			clear(&pc);
			break;
		case 7:
			sort(&pc);
			break;
		default:
			printf("输入错误\n");
			break;
		}
	}
	return 0;
}

总结

以上就是对简易通讯录的实现,主要是理解结构体方面的知识点,当学到了动态内存管理之后,也可对通讯录的内存容量进行动态管理,这样更能节省内存空间动态内存管理功能
如有不对之处望指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值