《小猫猫大课堂》三轮4——自定义类型(位段,枚举,联合)(内含通讯录)

宝子,你不点个赞吗?不评个论吗?不收个藏吗?

最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!!

喵喵喵,你对我真的很重要。

目录

前言

位段

枚举

联合(共用体)

通讯录

0.源码(解说见后)

1.创建文件

2.打印菜单,明确功能

3.创建通讯录

4.初始化通讯录和添加联系人

5.展示通讯录

 6.删除指定联系人

7.查找指定联系人 

8.修改指定联系人

9.联系人排序

10.删除所有联系人

总结


前言

闹腾太久了,累了,小喵想静静,想抱抱自己。


位段

位段的声明和结构(结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。)是类似的,有两个不同:

1.位段的成员必须是 int、char,unsigned int 或signed int 。(同类型)

2.位段的成员名后边有一个冒号和一个数字。

位段的位是二进制位
struct A
{
 int _a:2;//两个比特位
 int _b:5;
 int _c:10;//10个比特位
 int _d:30;//单个成员不能超过32,因为一个整形32个比特位
};
int main()
{
printf("%d\n", sizeof(struct A));//结果是8
return 0;
}

和结构体一样,该怎么用,一样用,只是位段更节省空间

位段的内存分配:

1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型

2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。

3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

位段的跨平台问题:(不同平台,写不同代码,这也是结构体的又是,它可以跨平台)

1. int 位段被当成有符号数还是无符号数是不确定的。

2. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机 器会出问题。

3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。

4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是 舍弃剩余的位还是利用,这是不确定的。


枚举

枚举顾名思义就是一一列举。 把可能的取值一一列举

enum Day//星期
{
 Mon,
 Tues,
 Wed,
 Thur,
 Fri,
 Sat,
 Sun
};
enum Sex//性别
{
 MALE,
 FEMALE,
 SECRET
};
enum Color//颜色
{
 RED,
 GREEN,
 BLUE
};

以上定义的 enum Day , enum Sex , enum Color 都是枚举类型。 {}中的内容是枚举类型的可能取值,也叫 枚举常量

这些可能取值都是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值。

enum Color//颜色
{
 RED,    //0
 GREEN,   //1
 BLUE     //2
};
enum Color//颜色
{
 RED=1,
 GREEN=2,
 BLUE=4
};

枚举的优点:

1. 增加代码的可读性和可维护性

2. 和#define定义的标识符比较枚举有类型检查,更加严谨。

3. 防止了命名污染(封装)

4. 便于调试

5. 使用方便,一次可以定义多个常量

现实生活中,我们能用枚举就用枚举。

enum Color//颜色
{
 RED=1,
 GREEN=2,
 BLUE=4
};
enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
clr = 5;               //ok??

联合(共用体)

联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。(成员不能同时一起用空间)

联合的特点:

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联 合至少得有能力保存最大的那个成员)

联合大小的计算:

  • 联合的大小至少是最大成员的大小。
  • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。


通讯录

0.源码(解说见后)

//Contact.h
#pragma once
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12

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

//人的信息
typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char addr[ADDR_MAX];
	char tele[TELE_MAX];
}PeoInfo;
  


struct contact
{
	struct PeoInfo data[NAME_MAX];
	int sz;//记录当前已经有的元素个数
};

typedef struct Contact
{
	PeoInfo data[1000];//存放人的信息
	int sz;//当前已存放信息的个数
}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact*pc);
 //删除指定联系人
void DelContact(Contact* pc);
//显示通讯录
void ShowContact(const Contact* pc);
//查找指定联系人
void SearchContact(Contact* pc);
//修改指定联系人
void ModifyContact(Contact* pc);
//联系人排序
void SortContact(Contact* pc);
//删除所有联系人
void DeaContact(Contact* pc);
//Contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include"contact.h"
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
}

void AddContact(Contact* pc)
{
	assert(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].addr);
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->sz].tele);
	pc->sz++;
}

void ShowContact(const Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-15s\n", "名字", "年龄", "性别", "地址", "电话");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-15s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele);
	}

}

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


void DelContact(Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除");
		return;
	}
	//删除
	//找出要删除的人
	printf("请输入要删除的人的名字;>");
	scanf("%s", name);
	int ret=FindByName(pc, name);
	if (-1 == ret)
	{
     printf("要删除的人不存在\n");
	 return;
	}
		

	int i = 0;
	int del = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			del = i;
			break;
		}
	}
	//删除
	for (i = del; i < pc->sz; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功\n");
}

void SearchContact(const Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	printf("请输入要查找人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		printf("要查找的人不存在\n");
		return;
	}
	//打印信息
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-15s\n", "名字", "年龄", "性别", "地址", "电话");
	printf("%-20s\t%-4d\t%-5s\t%-20s\t%-15s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].addr, pc->data[pos].tele);
}

void ModifyContact(Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	printf("请输入要删除的人的名字;>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		printf("要删除的人不存在\n");
		return;
	}
	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].addr);
	printf("请输入电话:>");
	scanf("%s", pc->data[pos].tele);
	printf("修改完成\n");
}

//排序函数
		//1.按照姓名进行排序
int Conpare_ByName(const void* e1, const void* e2)
{
	return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}
//2.按照年龄进行排序
int Conpare_ByAge(const void* e1, const void* e2)
{
	return ((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age;
}
//3.按照住址进行排序
int Conpare_ByAddress(const void* e1, const void* e2)
{
	return strcmp(((struct PeoInfo*)e1)->addr, ((struct PeoInfo*)e2)->addr);
}
void SortContact(Contact* pc)
{
	assert(pc);
		
		printf("请选择你想排序的方式:\n");
		printf("1.姓名\n2.年龄\n3.住址\n");
		int input = 0;
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByName);
			printf("排序成功\n");
			break;
		case 2:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByAge);
			printf("排序成功\n");
			break;
		case 3:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByAddress);
			printf("排序成功\n");
			break;
		}
}


void DeaContact(Contact* pc)
{
	assert(pc);
	memset(pc->data, 0, sizeof(pc->data));
	pc->sz == 0;
	printf("清空成功!\n");

}
//teat.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#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("*****   7.dea     0.exit   ******\n");
	printf("*********************************\n");
}
int main()
{
	int input = 0;
	//创建通讯录
	PeoInfo  data[1000];
	int sz=05l;
	Contact con;
	//初始化通讯录
	InitContact(&con);
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		switch (input)
		{
		case  1:
			AddContact(&con);
			break;
		case  2:
			DelContact(&con);
			break;
		case  3:
			SearchContact(&con);
			break;
		case  4:
			ModifyContact(&con);
			break;
		case  5:
			ShowContact(&con);
			break;
		case  6:
			SortContact(&con);
			break;
		case  7:
			DeaContact(&con);
			break;
		case  0:
			printf("退出游戏");
			break;
		default:
			printf("选择错误");
			break;
		}
	} while (input);
	return 0;
}

1.创建文件

test.c——测试通讯录

contact.c——通讯录的实现

contact.h——函数的声明


2.打印菜单,明确功能

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#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("*****   7.sort    0.exit   ******\n");
	printf("*********************************\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  7:
			break;
		case  0:
			printf("退出游戏");
			break;
		default:
			printf("选择错误");
			break;
		}
	} while (input);
	return 0;
}

3.创建通讯录

//头文件
#pragma once
//人的信息
typedef struct PeoInfo
{
	char name[20];
	int age;
	char sex[5];
	char addr[30];
	char tele[12];
}PeoInfo;
  
typedef struct Contact
{
	PeoInfo data[1000];//存放人的信息
	int sz;//当前已存放信息的个数
}Contact;

4.初始化通讯录和添加联系人

test.c

 

//Contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"contact.h"
void InitContact(Contact* pc)
{
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
}

AddContact(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].addr);
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->sz].tele);
	pc->sz++;
}

5.展示通讯录

test.c

头文件声明

//Contact.c(实现)
void ShowContact(Contact* pc)
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%s\t%d\t%s\t%s\t%s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele);
	}

}

阶段性测试(输入数据可使用中文)  

 数据右对齐

void ShowContact(Contact* pc)
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%20s\t%4d\t%5s\t%20s\t%15s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele);
	}

}

数据左对齐

void ShowContact(Contact* pc)
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-15s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele);
	}

}

加表头明确数据

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

}

 6.删除指定联系人

先声明(Contact.h)

 引用删除的子程序(test.h)

 Contact.c

void DelContact(Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除");
		return;
	}
	//删除
	//找出要删除的人
	printf("请输入要删除的人的名字;>");
	scanf("%s", name);
	int i = 0;
	int del = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			del = i;
			break;
		}
	}
	//删除
	for (i = del; i < pc->sz; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功\n");
}

阶段性测试:

如果删除的联系人不存在,要做出提示

应该先找出需删除的联系人,判断其是否存在。

int FindByName(const 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 DelContact(Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除");
		return;
	}
	//删除
	//找出要删除的人
	printf("请输入要删除的人的名字;>");
	scanf("%s", name);
	int ret=FindByName(pc, name);
	if (-1 == ret)
	{
     printf("要删除的人不存在\n");
	 return;
	}
		

	int i = 0;
	int del = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			del = i;
			break;
		}
	}
	//删除
	for (i = del; i < pc->sz; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功\n");
}

 阶段性测试(判断代码实现效果)


7.查找指定联系人 

记得声明和引用哈

void SearchContact(const Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	printf("请输入要查找人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		printf("要查找的人不存在\n");
		return;
	}
	//打印信息
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-15s\n", "名字", "年龄", "性别", "地址", "电话");
	printf("%-20s\t%-4d\t%-5s\t%-20s\t%-15s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].addr, pc->data[pos].tele);
}

阶段性测试


8.修改指定联系人

记得声明和引用哈

void ModifyContact(Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	printf("请输入要删除的人的名字;>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		printf("要删除的人不存在\n");
		return;
	}
	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].addr);
	printf("请输入电话:>");
	scanf("%s", pc->data[pos].tele);
    printf("修改完成");
}

阶段性测试: 


9.联系人排序

记得声明和引用哈

//排序函数
		//1.按照姓名进行排序
int Conpare_ByName(const void* e1, const void* e2)
{
	return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}
//2.按照年龄进行排序
int Conpare_ByAge(const void* e1, const void* e2)
{
	return ((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age;
}
//3.按照住址进行排序
int Conpare_ByAddress(const void* e1, const void* e2)
{
	return strcmp(((struct PeoInfo*)e1)->addr, ((struct PeoInfo*)e2)->addr);
}
void SortContact(Contact* pc)
{
	assert(pc);
		
		printf("请选择你想排序的方式:\n");
		printf("1.姓名\n2.年龄\n3.住址\n");
		int input = 0;
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByName);
			printf("排序成功\n");
			break;
		case 2:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByAge);
			printf("排序成功\n");
			break;
		case 3:
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), Conpare_ByAddress);
			printf("排序成功\n");
			break;
		}
}


10.删除所有联系人

记得声明和引用哈

void DeaContact(Contact* pc)
{
	assert(pc);
	memset(pc->data, 0, sizeof(pc->data));
	pc->sz == 0;
	printf("清空成功!\n");

}


总结

即使结束也是开始,来,我们干了这碗鸡汤。


宝子,你不点个赞吗?不评个论吗?不收个藏吗?

最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!!

喵喵喵,你对我真的很重要。 

猜你喜欢

转载自blog.csdn.net/ormstq/article/details/128690843