• 静态通讯录


    在这里插入图片描述
    今天我们分享一下静态通讯录详细解释和代码,之前分享过的只是通讯录的代码,但是我们没有进行讲解和解释,今天我们一边分享它的代码一边解释原因,让大家可以手撕通讯录。现在开始我们的学习吧。

    首先我们应该要有三个文件,一个是来放我们的代码就是拿来测试的,我们叫他为test.c,一个就是我们来声明,比如一些函数或者结构体的声明,我们就应该放到这个里面,还有就是定义,我们函数是个怎么样的,怎么实现的我们也需要一个源文件来实现。

    在这里插入图片描述
    创建好这三个之后我们需要在我们的test.c里面写上我们的菜单,首先我们通讯录是不是一定要具备增删查改的功能,其实还有可以查找,或者排序的功能,那我们先简单的实现一下菜单。

    在这里插入图片描述
    我们简单的菜单就这样制成了,接下来我们需要做的就就是用switch函数来实现我们选啥就进入哪一个的操作,比如我们要进入add增加用户,那哦我们输入1就行了

    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.sort **\n");
    	printf("***0.exit           **\n");
    }
    int main()
    {
    	int input = 0;
    	do
    	{
    		menu();
    		printf("请输入你要进行的操作>");
    		scanf("%d", &input);
    		switch (input)
    		{
    		case 1:
    			break;
    		case 2:
    			break;
    		case 3:
    			break;
    		case 4:
    			break;
    		case 5:
    			break;
    		case 6:
    			break;
    		case 0:
    			printf("退出通讯录\n");
    			break;
    		default:
    			printf("输入错误,请重新选择\n");
    			break;
    		}
    	} while (input);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    这样看其实我们的代码的可读性并不是很高,所以我们需要进行修改,大家可以看看我的上一篇文章,写的就是有一个枚举的例子,这里我们如果用的是枚举的话,看起来代码的可读性就高很多了,那我们改一下代码

    #include"Contact.h"
    
    enum Option
    {
    	EXIT,
    	ADD,
    	DEL,
    	SEARCH,
    	MODIFY,
    	SHOW,
    	SORT
    };
    void menu()
    {
    	printf("**********************\n");
    	printf("***1.add     2.del ***\n");
    	printf("***3.search  4.modify*\n");
    	printf("***5.show    6.sort **\n");
    	printf("***0.exit           **\n");
    }
    int main()
    {
    	int input = 0;
    	do
    	{
    		menu();
    		printf("请输入你要进行的操作>");
    		scanf("%d", &input);
    		switch (input)
    		{
    		case ADD:
    			break;
    		case DEL:
    			break;
    		case SEARCH:
    			break;
    		case MODIFY:
    			break;
    		case SHOW:
    			break;
    		case SORT:
    			break;
    		case EXIT:
    			printf("退出通讯录\n");
    			break;
    		default:
    			printf("输入错误,请重新选择\n");
    			break;
    		}
    	} while (input);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    我们这样看的话是不是可读性就稍微高一点了。
    完成上面的代码,我们来思考一下我们的通讯录需要存什么东西,我们是不是拿来存人的,所以我们需要这个人的名字,年龄,性别,电话号码,还有这个人的地址,那我们现在需要做的就是定义一个结构体,结构体我们需要的是把他放入到Contact.h中

    在这里插入图片描述

    typedef struct PeoInf
    {
    	char name[20];
    	int age;
    	char sex[5];
    	char tel[12];
    	char addr[20];
    }PeoInf;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    有了这个结构体我们还需要一个东西来统计它的个数,比如通讯录里面有几个人,这应该是一个局部变量,所以这里我们要做的就是在写一个结构体来实现

    typedef struct PeoInf
    {
    	char name[20];
    	int age;
    	char sex[5];
    	char tel[12];
    	char addr[20];
    }PeoInf;
    
    
    
    struct Contact
    {
    	PeoInf data[100];
    	int sz;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    上面的代码固然是好,但是我们还是存在一定的缺陷,缺陷是什么呢,我们结构体的数组好像是定死的,本来静态的通讯录就缺少一点动态,我们还把它定死,那比如我们像存101个人,这样不就是改改很麻烦,所以我们可以这样写

    #define N 100
    #define NMAE_MAX 20
    #define SEX_MAX 5
    #define TEL_MAX 12
    #define ADDR_MAX 20
    
    typedef struct PeoInf
    {
    	char name[NMAE_MAX];
    	int age;
    	char sex[SEX_MAX];
    	char tel[TEL_MAX];
    	char addr[ADDR_MAX];
    }PeoInf;
    
    
    
    typedef struct Contact
    {
    	PeoInf data[N];
    	int sz;
    }Contact;
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    这样就好很对,那我们现在来初始化一下我们的Conact吧

    在这里插入图片描述
    我们看到这里也是成功的将我们的数据初始化,那来看看我们的代码吧

    void InitContact(Contact* pc)
    {
    	assert(pc);
    	memset(pc->data, 0, sizeof(pc->data));
    	pc->sz = 0; 
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码也是很简短,但是我们这里必须得传我们的指针过来,否则就不行了,我们要做的是改变结构体中内容,所以就得传他们的地址过来才行,那我们继续来实现下一个吧,下一个我们实现一下ADD吧

    void AddContact(Contact* ps)
    {
    	assert(ps);
    	assert(ps->sz <= N);//断言如果通讯录满了就不能加了
    	printf("请输入名字\n");
    	scanf("%s", ps->data[ps->sz].name);
    	printf("请输入年龄\n");
    	scanf("%d", &ps->data[ps->sz].age);
    	printf("请输入性别\n");
    	scanf("%s", ps->data[ps->sz].sex);
    	printf("请输入电话\n");
    	scanf("%s", ps->data[ps->sz].tel);
    	printf("请输入地址\n");
    	scanf("%s", ps->data[ps->sz].addr);
    	ps->sz++;
    	printf("增加成功\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    上面就是我们进行增加通讯录的代码,写完这个我们在加一个printf数据的代码也就是显示(show)

    void ShowContact(Contact* ps)
    {
    	assert(ps);
    	int i = 0;
    	printf("%-20s%-5s%-5s%-12s%-12s\n", "姓名", "年龄", "性别", "电话", "地址");
    	for (i = 0; i < ps->sz; i++)
    	{
    		printf("%-20s%-5d%-5s%-12s%-12s\n",
    			ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tel, ps->data[i].addr);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    为了让我们的打印显示起来好看一点,我们这里加了对齐,看起来就比较整齐,小编的代码是右对齐,大家也可以进行左对齐的形式,上面的两个代码其实也没有什么要需要注意的,考察的就是对结构体的了解和怎么使用。我们下面来看我们后面的接口函数吧

    下一个接口函数就是我们的删除,删除可不是随机删除人,比如我们先要找到这个人的名字,然后进行删除,在删除之前是不是还要看一下通讯录里面还有没有人,如果没有人的话,我们就不能进行删除了,所以这里我们进行强制断言一下

    int FindByName(Contact* ps, char name[])
    {
    	assert(ps);
    	int i = 0;
    	for (i = 0; i < ps->sz; i++)
    	{
    		if (strcmp(ps->data[i].name, name) == 0)
    			return i;
    	}
    	return -1;
    }
    void DelContact(Contact* ps)
    {
    	assert(ps);
    	assert(ps->sz > 0);
    	char name[NMAE_MAX];
    	printf("请输入要删除的人的名字>");
    	scanf("%s", name);
    	int ret = FindByName(ps, name);
    	if (ret == -1)
    	{
    		printf("通讯录没有这个人\n");
    		return ;
    	}
    	int i = 0;
    	for (i = ret; i < ps->sz - 1; i++)
    	{
    		ps->data[i] = ps->data[i + 1];
    	}
    	ps->sz--;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    上面的FIndByName是我们自己写的一个函数,只能在这个文件中使用,所以我们也可以用static修饰一下,就变成这样了

    static int FindByName(Contact* ps, char name[])
    {
    	assert(ps);
    	int i = 0;
    	for (i = 0; i < ps->sz; i++)
    	{
    		if (strcmp(ps->data[i].name, name) == 0)
    			return i;
    	}
    	return -1;
    }
    void DelContact(Contact* ps)
    {
    	assert(ps);
    	assert(ps->sz > 0);
    	char name[NMAE_MAX];
    	printf("请输入要删除的人的名字>");
    	scanf("%s", name);
    	int ret = FindByName(ps, name);
    	if (ret == -1)
    	{
    		printf("通讯录没有这个人\n");
    		return ;
    	}
    	int i = 0;
    	for (i = ret; i < ps->sz - 1; i++)
    	{
    		ps->data[i] = ps->data[i + 1];
    	}
    	ps->sz--;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    这里调试个人感觉特别麻烦,因为我们每次调试一个接口函数的时候,都要重新输入,这是为什么呢,因为我们的数据是存储在内存中的,程序运行结束的时候,我们的数据是无法进行保存的,只要存储在数据库或者文件中,数据才能进行保存,那现在我们来看一下下个接口函数的实现吧

    下面一个接口函数就是查找了,查找很简单,我们就不过多解释,直接来看代码吧

    void SearchContact(Contact* ps)
    {
    	assert(ps);
    	char name[NMAE_MAX];
    	printf("要查找人的名字>");
    	scanf("%s", name);
    	int ret = FindByName(ps, name);
    	if (ret == -1)
    	{
    		printf("找不到这个人");
    		return;
    	}
    	printf("%-20s%-5d%-5s%-12s%-12s\n",
    		ps->data[ret].name, ps->data[ret].age, ps->data[ret].sex, ps->data[ret].tel, ps->data[ret].addr);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    下面我们增删查改还有一个改的环节,改的话我们首先是不是要找到这个人,然后对它进行修改就行了。

    void ModifyContact(Contact* ps)
    {
    	assert(ps);
    	char name[NMAE_MAX];
    	printf("要查找人的名字>");
    	scanf("%s", name);
    	int ret = FindByName(ps, name);
    	if (ret == -1)
    	{
    		printf("找不到这个人");
    		return;
    	}
    	printf("请输入名字\n");
    	scanf("%s", ps->data[ret].name);
    	printf("请输入年龄\n");
    	scanf("%d", &ps->data[ret].age);
    	printf("请输入性别\n");
    	scanf("%s", ps->data[ret].sex);
    	printf("请输入电话\n");
    	scanf("%s", ps->data[ret].tel);
    	printf("请输入地址\n");
    	scanf("%s", ps->data[ret].addr);
    	printf("修改成功\n");
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    最后还剩下一个排序,这里我们就假设是按年龄来进行排序的吧,排序大家还记不记得我们有一个库函数,之前我们用冒泡函数来模拟实现,并且我们也掌握它的用法,那这里我们就直接用库函数qsort来实现吧

    int CmpByAge(const void* p1, const void* p2)
    {
    	return *(int*)p1 - *(int*)p2;
    }
    void SortContact(Contact* ps)
    {
    	assert(ps);
    	qsort(ps->data, N, sizeof(ps->data[0]), CmpByAge);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这样就可以了

    那来看一下我们的完整代码吧

    Contact.h

    #pragma once
    
    
    
    #include
    #include
    #include
    #include
    
    #define N 100
    #define NMAE_MAX 20
    #define SEX_MAX 5
    #define TEL_MAX 12
    #define ADDR_MAX 20
    
    typedef struct PeoInf
    {
    	char name[NMAE_MAX];
    	int age;
    	char sex[SEX_MAX];
    	char tel[TEL_MAX];
    	char addr[ADDR_MAX];
    }PeoInf;
    
    
    
    typedef struct Contact
    {
    	PeoInf data[N];
    	int sz;
    }Contact;
    
    //初始化
    void InitContact(Contact* pc);
    
    
    void AddContact(Contact* ps);
    
    void ShowContact(Contact* ps);
    
    void DelContact(Contact* ps);
    
    
    void SearchContact(Contact* ps);
    
    
    void ModifyContact(Contact* ps);
    
    void SortContact(Contact* ps);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    Contact.c

    #define _CRT_SECURE_NO_WARNINGS 1
    
    #include"Contact.h"
    
    
    void InitContact(Contact* pc)
    {
    	assert(pc);
    	memset(pc->data, 0, sizeof(pc->data));
    	pc->sz = 0; 
    
    }
    
    void AddContact(Contact* ps)
    {
    	assert(ps);
    	assert(ps->sz <= N);//断言如果通讯录满了就不能加了
    	printf("请输入名字\n");
    	scanf("%s", ps->data[ps->sz].name);
    	printf("请输入年龄\n");
    	scanf("%d", &ps->data[ps->sz].age);
    	printf("请输入性别\n");
    	scanf("%s", ps->data[ps->sz].sex);
    	printf("请输入电话\n");
    	scanf("%s", ps->data[ps->sz].tel);
    	printf("请输入地址\n");
    	scanf("%s", ps->data[ps->sz].addr);
    	ps->sz++;
    	printf("增加成功\n");
    }
    
    void ShowContact(Contact* ps)
    {
    	assert(ps);
    	int i = 0;
    	printf("%-20s%-5s%-5s%-12s%-12s\n", "姓名", "年龄", "性别", "电话", "地址");
    	for (i = 0; i < ps->sz; i++)
    	{
    		printf("%-20s%-5d%-5s%-12s%-12s\n",
    			ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tel, ps->data[i].addr);
    	}
    }
    int FindByName(Contact* ps, char name[])
    {
    	assert(ps);
    	int i = 0;
    	for (i = 0; i < ps->sz; i++)
    	{
    		if (strcmp(ps->data[i].name, name) == 0)
    			return i;
    	}
    	return -1;
    }
    void DelContact(Contact* ps)
    {
    	assert(ps);
    	assert(ps->sz > 0);
    	char name[NMAE_MAX];
    	printf("请输入要删除的人的名字>");
    	scanf("%s", name);
    	int ret = FindByName(ps, name);
    	if (ret == -1)
    	{
    		printf("通讯录没有这个人\n");
    		return;
    	}
    	int i = 0;
    	for (i = ret; i < ps->sz - 1; i++)
    	{
    		ps->data[i] = ps->data[i + 1];
    	}
    	ps->sz--;
    }
    
    void SearchContact(Contact* ps)
    {
    	assert(ps);
    	char name[NMAE_MAX];
    	printf("要查找人的名字>");
    	scanf("%s", name);
    	int ret = FindByName(ps, name);
    	if (ret == -1)
    	{
    		printf("找不到这个人");
    		return;
    	}
    	printf("%-20s%-5d%-5s%-12s%-12s\n",
    		ps->data[ret].name, ps->data[ret].age, ps->data[ret].sex, ps->data[ret].tel, ps->data[ret].addr);
    
    }
    
    
    void ModifyContact(Contact* ps)
    {
    	assert(ps);
    	char name[NMAE_MAX];
    	printf("要查找人的名字>");
    	scanf("%s", name);
    	int ret = FindByName(ps, name);
    	if (ret == -1)
    	{
    		printf("找不到这个人");
    		return;
    	}
    	printf("请输入名字\n");
    	scanf("%s", ps->data[ret].name);
    	printf("请输入年龄\n");
    	scanf("%d", &ps->data[ret].age);
    	printf("请输入性别\n");
    	scanf("%s", ps->data[ret].sex);
    	printf("请输入电话\n");
    	scanf("%s", ps->data[ret].tel);
    	printf("请输入地址\n");
    	scanf("%s", ps->data[ret].addr);
    	printf("修改成功\n");
    
    }
    
    
    int CmpByAge(const void* p1, const void* p2)
    {
    	return *(int*)p1 - *(int*)p2;
    }
    void SortContact(Contact* ps)
    {
    	assert(ps);
    	qsort(ps->data, N, sizeof(ps->data[0]), CmpByAge);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128

    接下来就是我们的测试代码

    test.c

    #define _CRT_SECURE_NO_WARNINGS 1
    
    
    
    #include"Contact.h"
    
    enum Option
    {
    	EXIT,
    	ADD,
    	DEL,
    	SEARCH,
    	MODIFY,
    	SHOW,
    	SORT
    };
    void menu()
    {
    	printf("********************************\n");
    	printf("***1.add     2.del *************\n");
    	printf("***3.search  4.modify***********\n");
    	printf("***5.show    6.sort ************\n");
    	printf("***0.exit           ************\n");
    }
    int main()
    {
    	int input = 0;
    	Contact p;
    	InitContact(&p);
    	do
    	{
    		menu();
    		printf("请输入你要进行的操作>");
    		scanf("%d", &input);
    		
    		switch (input)
    		{
    		case ADD:
    			AddContact(&p);
    			break;
    		case DEL:
    			DelContact(&p);
    			break;
    		case SEARCH:
    			SearchContact(&p);
    			break;
    		case MODIFY:
    			ModifyContact(&p);
    			break;
    		case SHOW:
    			ShowContact(&p);
    			break;
    		case SORT:
    			SortContact(&p);
    			break;
    		case EXIT:
    			printf("退出通讯录\n");
    			break;
    		default:
    			printf("输入错误,请重新选择\n");
    			break;
    		}
    	} while (input);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    这就是我们今天的分享,我们第一次是只分享了代码,这次我们就把整个过程以讲解的方式讲解出来,谢谢大家,我们下次再见

  • 相关阅读:
    【.Net】Linq的使用
    如何执行建设项目的时间影响分析?
    【硬件专题】案例:热敏打印效果差?为什么是多个因素造成的?
    《Web安全基础》09. WAF 绕过
    【LeetCode15. 三数之和】——set型哈希表、双指针法
    如何分析Apple搜索广告效果
    面试求职者
    Spring让人眼前一亮的11个小技巧
    C++ 正则表达式使用
    解决ThinkPHP6设置session不生效的问题 - exit/die以前的session写入都无效的问题
  • 原文地址:https://blog.csdn.net/2301_76895050/article/details/133238410