C语言动态与静态分别实现通讯录详细过程

目录
  • 前言:
  • 一.静态通讯录的实现
    • 1.环境的分工逻辑
    • 2.待实现的功能
    • 3.contact.h
    • 4.contact.c
    • 5.test.c
    • 6.实现效果
  • 二.通讯录动态的实现
    • 1.contact.h
    • 2.contact.c
    • 3.test.c

前言:

通讯录相信每一个人都了解过

它的功能包括简单包括:增删查改

这一期就来实现一个C语言实现的通讯录

续上次所聊到的--动态内存的分配

那么我会从标题所给的两个方式来实现

一.静态通讯录的实现

1.环境的分工逻辑

由于过程有点长,便于理解,所以一共会用到三个文件

分别是两个源文件test.c、contact.c ,还有一个头文件contact.h来实现

test.c是主体,是通讯录的测试逻辑

contact.c是通讯录的实现逻辑

contact.h是实现通讯录函数的声明

2.待实现的功能

通讯录的每一个功能是相对独立的

所以可以分别用不同的函数来实现各个部分的功能

contact.c包含的函数分别以下内容:

1.结构体的初始化

2.添加联系人

3.展示联系人

4.删除联系人

5.查找联系人

6.修改联系人

具体代码如下:

3.contact.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
//通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
typedef struct  Introduction
{
	char name[20];
	char sex[10];
	int  age;
	char tele[20];
	char addr[30];
} Introduction;
typedef struct contact
{
	Introduction data[1000];
	int sz;
}contact;

//结构体的初始化
void Initcontact(contact* pc);
//添加联系人
void Add(contact* pc);
//展示联系人
void show(contact* pc);
//删除联系人
void Dele(contact* pc);
//查找联系人
void Find(contact* pc);
//修改联系人
void Exchange(contact* pc);

4.contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
void Initcontact(contact* pc)//结构体的初始化
{
    pc->sz = 0;
    memset(pc->data, 0, sizeof(pc->data));
}

void Add(contact* pc)//添加联系人
{
    //判断是否未满
    if (pc->sz == 1000)
    {
        printf("通讯录已满\n");
        return;
    }
    printf("请输入名字>:");
    scanf("%s", pc->data[pc->sz].name);
    printf("请输入年龄>:");
    scanf("%d", &(pc->data[pc->sz].age));
    printf("请输入性别:>");
    scanf("%s", pc->data[pc->sz].sex);
    printf("请输入电话:>");
    scanf("%s", pc->data[pc->sz].tele);
    printf("请输入地址:>");
    scanf("%s", pc->data[pc->sz].addr);
    pc->sz++;
    printf("增加联系人成功\n");
}

void show(contact* pc)//展示联系人
{
    int i = 0;
    printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t\n ", "名字", "年龄", "性别", "电话", "地址");
    for (i = 0; i < pc->sz; i++)
    {
        printf("%-10s\t%-10d\t%-10s\t%-10s\t%-10s\t\n ",
        pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
    }
}

int SearchByName(contact* pc, char name[])
{
    int i = 0;
    for (i = 0; i < pc->sz; i++)
    {
        if (strcmp(pc->data[i].name, name) == 0)
        {
            return i;
        }
    }
    return -1;
}

void Dele(contact* pc)//删除联系人
{
    int i = 0; char name[10];
    printf("输入要删除人的名字>:\n");
    scanf("%s", name);
    if (pc->sz == 0)
    {
        printf("通讯录为空,无法删除\n");
    }
    //判断是否有联系人
    int pos = SearchByName(pc, name);
    if (pos == -1)
    {
        printf("找不到联系人\n");
    }
    else
    {
        for (i = pos; i < pc->sz - 1; i++)
        {
            pc->data[i] = pc->data[i + 1];
        }
        pc->sz--;
        printf("删除联系人成功\n");
    }
}

void Find(contact* pc)//查找联系人
{
    char name[10];
    printf("输入要查找人的名字>:\n");
    scanf("%s", name);
    int pos = SearchByName(pc, name);
    if (pos == -1)
    {
        printf("通讯录中无查找人的名字");
    }
    else
    {
        printf("查找的人信息为:>");
        printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t\n ", "名字", "年龄", "性别", "电话", "地址");
        printf("%-10s\t%-10d\t%-10s\t%-10s\t%-10s\t\n ",
        pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr);
    }
}

void Exchange(contact* pc)//修改联系人
{
    char name[10];
    printf("输入要修改人的名字>:\n");
    scanf("%s", name);
    int pos = SearchByName(pc, name);
    if (pos == -1)
    {
        printf("通讯录中无修改人的名字");
    }
    else
    {
        printf("请输入名字>:");
        scanf("%s", pc->data[pos].name);
        printf("请输入年龄>:");
        scanf("%d", &(pc->data[pos].age));
        printf("请输入性别:>");
        scanf("%s", pc->data[pos].sex);
        printf("请输入电话:>");
        scanf("%s", pc->data[pos].tele);
        printf("请输入地址:>");
        scanf("%s", pc->data[pos].addr);
        printf("修改成功");
    }
}
 

5.test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
void menu()
{
	printf("**********************************************\n");
	printf("*******     1.Add        2.Dele      *********\n");
	printf("*******     3.Find       4.Exchange **********\n");
	printf("*******     5.show       0.exit     **********\n");
	printf("**********************************************\n");
}
int main()
{
	int input = 0;
	contact con;
    Initcontact(&con);
	do
	{
		menu();
		printf("请输入一个数>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			Add(&con);
			break;
		case 2:
			Dele(&con);
			break;
		case 3:
			Find(&con);
			break;
		case 4:
			Exchange(&con);
			break;
		case 5:
			show(&con);
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误\n");
		}

	} while (input);
	return 0;
}

6.实现效果

二.通讯录动态的实现

相较于静态的实现,两者的差别并不大

前者是用一个固定数组来实现元素的储存

后者则是用动态申请的内存来实现储存,优点是可以节省内存

区别在于

通讯录的初始化,这里引用了capcity容量来比较已有的容量

来判断内存的使用量,便于扩容

其次就是Add函数,增加联系人

最后再对释放的内存进行释放

代码如下:

1.contact.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>

typedef struct Introduction
{
	char name[20];
	char sex[10];
	int  age;
	char tele[20];
	char addr[30];
}Introduction;

typedef struct contact
{
	Introduction* data;
	int sz;
	int capcity;
}contact;

//结构体的初始化
void Initcontact(contact* pc);
//添加联系人
void Add(contact* pc);
//展示联系人
void show(contact* pc);
//删除联系人
void Dele(contact* pc);
//查找联系人
void Find(contact* pc);
//修改联系人
void Exchange(contact* pc);
//销毁通讯录
void destroy(contact*pc);

2.contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
#define TARGET_sz 3   //初始通讯录目标容量 

void Initcontact(contact* pc)//结构体的初始化
{
    assert(pc);//判断指针的有效性
    pc->sz = 0;
    contact* tmp = 0;
    tmp=(contact*)malloc(sizeof(Introduction)*TARGET_sz);
    if (tmp!=NULL)
    {
        pc->data = tmp;
    }
    else
    {
        printf("扩容失败,请检查原因\n");
        return;
    }
    pc->capcity = TARGET_sz;
}

void Add(contact* pc)//添加联系人
{
    assert(pc);
    if (pc->capcity == pc->sz)
    {
        Introduction* tmp = 0;
        tmp=(Introduction*)realloc(pc->data,sizeof(Introduction)*(pc->capcity+2));
        if (tmp != NULL)
        {
            pc->capcity += 2;
            pc->data = tmp;
            printf("扩容成功\n");
        }
        else
        {
            printf("扩容失败,请检查原因\n");
        }
    }
    printf("请输入名字>:");
    scanf("%s", pc->data[pc->sz].name);
    printf("请输入年龄>:");
    scanf("%d", &(pc->data[pc->sz].age));
    printf("请输入性别:>");
    scanf("%s", pc->data[pc->sz].sex);
    printf("请输入电话:>");
    scanf("%s", pc->data[pc->sz].tele);
    printf("请输入地址:>");
    scanf("%s", pc->data[pc->sz].addr);
    pc->sz++;
    printf("增加联系人成功\n");
}

void show(contact* pc)//展示联系人
{
    int i = 0;
    printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t\n ", "名字", "年龄", "性别", "电话", "地址");
    for (i = 0; i < pc->sz; i++)
    {
        printf("%-10s\t%-10d\t%-10s\t%-10s\t%-10s\t\n ",
            pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
    }
}

int SearchByName(contact* pc, char name[])
{
    int i = 0;
    for (i = 0; i < pc->sz; i++)
    {
        if (strcmp(pc->data[i].name, name) == 0)
        {
            return i;
        }
    }
    return -1;
}

void Dele(contact* pc)//删除联系人
{
    int i = 0; char name[10];
    printf("输入要删除人的名字>:\n");
    scanf("%s", name);
    if (pc->sz == 0)
    {
        printf("通讯录为空,无法删除\n");
    }
    //判断是否有联系人
    int pos = SearchByName(pc, name);
    if (pos == -1)
    {
        printf("找不到联系人\n");
    }
    else
    {
        for (i = pos; i < pc->sz - 1; i++)
        {
            pc->data[i] = pc->data[i + 1];
        }
        pc->sz--;
        printf("删除联系人成功\n");
    }
}

void Find(contact* pc)//查找联系人
{
    char name[10];
    printf("输入要查找人的名字>:\n");
    scanf("%s", name);
    int pos = SearchByName(pc, name);
    if (pos == -1)
    {
        printf("通讯录中无查找人的名字");
    }
    else
    {
        printf("查找的人信息为:>");
        printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\t\n ", "名字", "年龄", "性别", "电话", "地址");
        printf("%-10s\t%-10d\t%-10s\t%-10s\t%-10s\t\n ",
        pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr);
    }
}

void Exchange(contact* pc)//修改联系人
{
    char name[10];
    printf("输入要修改人的名字>:\n");
    scanf("%s", name);
    int pos = SearchByName(pc, name);
    if (pos == -1)
    {
        printf("通讯录中无修改人的名字");
    }
    else
    {
        printf("请输入名字>:");
        scanf("%s", pc->data[pos].name);
        printf("请输入年龄>:");
        scanf("%d", &(pc->data[pos].age));
        printf("请输入性别:>");
        scanf("%s", pc->data[pos].sex);
        printf("请输入电话:>");
        scanf("%s", pc->data[pos].tele);
        printf("请输入地址:>");
        scanf("%s", pc->data[pos].addr);
        printf("修改成功");
    }
}
void destroy(contact* pc)
{
    assert(pc);
    free(pc->data);
    pc->data = NULL;
    pc->capcity = 0;
    pc->sz = 0;
}
 

3.test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
void menu()
{
	printf("**********************************************\n");
	printf("*******     1.Add        2.Dele      *********\n");
	printf("*******     3.Find       4.Exchange **********\n");
	printf("*******     5.show       0.exit     **********\n");
	printf("**********************************************\n");
}
int main()
{
	int input = 0;
	contact con;
	Initcontact(&con);
	do
	{
		menu();
		printf("请输入一个数>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			Add(&con);
			break;
		case 2:
			Dele(&con);
			break;
		case 3:
			Find(&con);
			break;
		case 4:
			Exchange(&con);
			break;
		case 5:
			show(&con);
			break;
		case 0:
			destroy(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误\n");
		}

	} while (input);
	return 0;
}

欢迎点赞收藏加关注,如若有问题可以提出来 

到此这篇关于C语言动态与静态分别实现通讯录详细过程的文章就介绍到这了,更多相关C语言 实现通讯录内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言静态与动态通讯录的实现流程详解

    目录 静态通讯录 contact.h contact.c test.c 动态通讯录 contact.h contact.c qsort.c test.c 本次通讯录的代码已经放到我的Gitee仓库中,感兴趣的小伙伴可以去看看 Gitee 静态通讯录 在我们学习完C语言的结构体.指针以及动态内存管理之后,我们就可以实现一些有意思的小项目了,通过这些小项目可以加深我们对于相关知识的理解. 静态通讯录主要要求有 静态大小,可以记录10个人的信息(大小自己定) 记录的信息如下:名字.性别.年龄.电话.住

  • C语言静态动态两版本通讯录实战源码

    目录 正片开始 静态版本 头文件( phonebook.h) 接口(test.c) 功能板块(phonebook.c) 1. 初始化: 2. 增添: 3.查找 4.删除 5.修改 6.排序 7.全览 静态版全部代码 test.c(接口) phonebook.h(头文件) phonebook.c(功能) 动态版 动态初始化: 扩容函数 动态版全部代码 test.c phonebook.h 正片开始 这里为了方便对照,我搬出整个程序的前后修改版本,并分别作为静态和动态版本,实际差距并不大,提供出来只

  • C语言实现通讯录的方法(包括静态版本和动态版本)

    目录 1.静态通讯录的实现 实现的方法: 2.动态通讯录的实现 实现的方法: 3.总结 1.静态通讯录的实现 实现的方法: 我们采用的方法就是工程形势,实现将功能和定义以及测试分成三个文件,其中定义放在.h文件,实现和测试放在.c文件当中. (1)contact.h文件的基本实现: #pragma once//防止头文件重复定义 #define NAME_MAX 20 #define SEX_MAX 5 #define TELE_MAX 12 #define ADDR_MAX 30 #defin

  • C语言动态与静态分别实现通讯录详细过程

    目录 前言: 一.静态通讯录的实现 1.环境的分工逻辑 2.待实现的功能 3.contact.h 4.contact.c 5.test.c 6.实现效果 二.通讯录动态的实现 1.contact.h 2.contact.c 3.test.c 前言: 通讯录相信每一个人都了解过 它的功能包括简单包括:增删查改 这一期就来实现一个C语言实现的通讯录 续上次所聊到的--动态内存的分配 那么我会从标题所给的两个方式来实现 一.静态通讯录的实现 1.环境的分工逻辑 由于过程有点长,便于理解,所以一共会用到

  • C语言实现可增容动态通讯录详细过程

    目录 创建可自动扩容的通讯录 添加用户信息 删除用户信息 查找联系人 修改用户信息 以名字将用户排序 销毁通讯录 创建可自动扩容的通讯录 这里我们想实现通讯录自动扩容,不够了能扩大内存,变得稍微有点智能,就不得不用到开辟内存的函数malloc和realloc,这两个函数又和free离不开关系 所以这里我给大家简单的介绍一下这三个库函数 malloc:这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针 void *malloc( size_t size ); 如果开辟成功,则返回一个指

  • C语言示例讲解动态/文件/静态功能版本的通讯录实现

    目录 一.代码展示 test.c contact.c contact.h 二.效果展示 静态版本基本功能的实现 动态版本扩容功能的实现 文件版本保存本地功能实现 一.代码展示 test.c 使用枚举类型,使得菜单部分的代码可读性更强,便于理解 #define _CRT_SECURE_NO_WARNINGS #include"contact.h" enum Option { EXIT, ADD, DEL, SEARCH, MODIFY, SHOW, SORT }; void menu()

  • C语言编程动态内存开辟实现升级版通讯录教程示例

    目录 前言 一.存放联系人信息 二.通讯录初始化 三.增加联系人 四.销毁通讯录 后记 前言 所谓动态内存开辟的通讯录,就是我需要多少联系人,就给多少联系人,防止给定一个联系人上限,需要增加联系人无法扩容,而联系人没有上限那么多又会造成内存浪费. 本文继之前的静态通讯录作出改进,有兴趣的同学可以看看之前的文章:C语言实现静态通讯录 一.存放联系人信息 这里是用struct PeoInfodata结构体指针指向通讯录,而不再直接 struct PeoInfo data[Max] 用结构体数组定义通

  • 浅谈Linux C语言动态库及静态库

    假设在math目录下已编辑好add.c sub.c div.c mul.c func_point.c文件,func_point.c为包含main()的源文件! 动态库的制作: 方法一: gcc -c -fPIC add.c sub.c div.c mul.c //-c表示生成.o目标文件,-f后加一些编译选项,PIC表示与位置无关 gcc -shared -o libmymath.so add.o sub.o mul.o div.o//创建共享库mymath,添加add.o,sub.o,mul.

  • C语言动态内存的分配实例详解

    目录 前言 动态内存分配的定义 动态内存的优势 <1>  可以控制内存的大小 <2> 可以多次利用这部分空间 <3>不占用栈区的内存 malloc calloc realloc和free函数的介绍 动态空间的申请与释放 为单个对象分配空间  为数组分配空间 改变申请的动态内存(realloc的使用) 扩容可能有三种情况 总结 前言 给数组分配多大的空间? 你是否和初学C时的我一样,有过这样的疑问. 这一期博客就来聊一聊动态内存的分配 读完这篇文章,你可能对内存的分配有一

  • C语言动态内存管理malloc柔性数组示例详解

    目录 1.1为什么存在动态内存管理 1.2动态内存管理函数 1.2.1malloc 1.2.2free 1.2.3calloc 1.2.4realloc 1.3动态内存管理函数易错点 1.3.1对NULL指针的解引用操作 1.3.2对动态开辟空间的越界访问 1.3.3对非动态开辟内存使用free释放 1.3.4使用free释放一块动态开辟内存的一部分 1.3.5对同一块动态内存多次释放 1.3.6动态开辟内存忘记释放(内存泄漏) 2.1常见相关笔试题 2.2C/C++语言中的内存开辟 2.3柔性

  • C语言 动态内存分配详解

    C语言 动态内存分配详解 动态内存分配涉及到堆栈的概念:堆栈是两种数据结构.堆栈都是数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除. 栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表. \在C语言中,全局变量分配在内存中的静态存储区,非静态的局部变量(包括形参)是分配在内存的动态存储区,该存储区被

  • 老生常谈C语言动态函数库的制作和使用(推荐)

    >>>>>>老生常谈C语言接静态函数库的制作和使用>>点击进入 2 动态函数库的制作和使用 动态函数库的制作步骤可以用下图来描述,具体包括 (1) 编写函数的.c文件(例如add.c.sub.c.mul.c和div.c) (2) 编写Makefile,然后make,实现函数的编译和归档入库 函数的编译:使用gcc –c add.c -fPIC只编译不链接函数.c文件,分别生成函数的目标文件(例如add.o.sub.o.mul.o和div.o). 函数的归档入

  • C语言动态内存分配函数的实现

    在C中我们开辟内存空间有两种方式 : 1.静态开辟内存 :例如: int a;int b[10]; 这种开辟内存空间的特点是 所开辟的内存是在栈中开辟的固定大小的 ,如a是4字节 ,数组b是40字节 ,并且数组在申明时必须指定其长度 , 如果是全局数组的话,内存是在编译时分配好的,如果是局部变量数组的话,运行时在栈上静态分配内存.不管是全局数组还是局部数组,它们都有一个特点,那就是数组大小是确定的,是代码中写死的.那如果我们想在程序运行时才确定一个数组的大小 , 前两种在栈上分配内存的方法显然是

随机推荐