0


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

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

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

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


前言

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


位段

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

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");

}


总结

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


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

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

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

标签: windows microsoft

本文转载自: https://blog.csdn.net/ormstq/article/details/128690843
版权归原作者 本喵是FW 所有, 如有侵权,请联系我们删除。

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

还没有评论