比特鹏哥网课笔记(结构体,枚举,联合体,通讯录项目)

1.结构体内存对齐

(1)在设计结构体时,既要满足对齐,又要节省空间(让占用空间小的成员尽量集中在一起) 

struct s1
{    char c1;
     char c2;
     int i;//占用8个字节
struct s2
{    char c1;
     int i;
     char c2;//占用12个字节

(2)修改默认对齐数

#pragma pack(4)  //设置为4 

#pragma pack()   //取消设置的默认对齐数

(3)写一个宏,计算结构体中某变量相对于首地址的偏移(百度笔试题)//offsetof宏

头文件#include<stddef.h>

printf("%d",offsetof(struct name,struct member name));

(4)位段,为了节省空间。但是不能跨平台

struct S
{
    int a:2;//是占据int型(4个字节*8=32bits中的2个比特位)
    int b:5;
    int c:15;
    int d:30;   //sizeof(S)=8个字节,a,b,c占据4个字节中的22个bit
int main()
{
    s.a=10;
    s.b=20;//是把数字先转化为二进制再存储
}

2.枚举(当需要define多个变量时,用枚举来代替)

#include<stdio.h>
enum Color
{
    RED,//0
    GREEN,//1
    BLUE  //2  枚举的可能取值——常量,main里面不能修改,
};
int main()
{
    enum Color c=BLUE;
    printf("%d %d %d",RED,GREEN,BLUE);//输出默认的0 1 2
    return 0;
}

3.联合体(共用体)

union Un
{
    char c;
    int i;
};
int main()
{
    union Un u;
    printf("%d\n",sizeof(u));//i和c不能同时使用

 面试题(判断当前计算机的大小端数据)

(1)大小端字节序问题

int check_sys
{
    union Un
    {
        int i;
        char c;
    }u;
    u.i=1;
    return u.c;//c本是char,以int型返回
}
int main()
{
    int a=1;  //寄存器里用16进制0x00000001 ,若小端,即01 00 00 00(<-------方向读取),
    int ret=check_sys();                     大端,即00 00 00 01(------->方向读取)
    if(1==ret) //转化成char*,是为了取一个字节看是00/01
    {
        printf(“小端”);
    }
    else printf("大端");
    //int a=0x11223344;//11是高字节,44是低字节
    //低地址------------------------>高地址
    //....[][][][][11][22][33][44][][][][][][]...大端字节序存储模式
    //....[][][][][44][33][22][11][][][][][][]...小端字节序存储模式(低对低)

(2)大小的计算

最大成员大小不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍

union Un
{
    int a;//4
    char arr[5];//字符数组的对齐数按照单个char来算~1,vs编译器中默认对齐数为8,
}   大小为8

实战项目(通讯录)

功能

1.存放1000个好友的信息

名字,电话,性别,住址,年龄

2.增加好友的信息

3.删除指定名字的好友信息

4.查找好友信息

5.修改好友信息

6.打印好友信息

7.排序

#define _CRT_SECURE_NO_WARNINGS 1//避免因为使用scanf,strcpy等不安全函数而报错
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX  5
#define MAX_TELE 12
#define MAX_ADDR 30
#include<stdio.h>
#include<string.h>
struct PeoInfo
{
    char name[MAX_NAME];
    int age;
    char sex[MAX_SEX];
    char tele[MAX_TELE];
    char addr[MAX_ADDR];
};
//创建通讯录类型
struct Contact
{
    struct PeoInfo data[MAX];
    int size;//记录当前已经有的元素个数
};
enum Option
{
    EXIT,//0
    ADD, //1
    DEL, //2
    SEARCH,
    MODIFY,
    SHOW,
    SORT
};//用枚举来把case中的0 1 2 3等替换,增加代码的可读性
void InitContact(struct Contact *ps)
{
    memset(ps->data,0,sizeof(ps->data));//将数组内元素设为0,用memset
    ps->size=0;
}
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");
    printf("****************************************\n");
}
void Addcontact(struct Contact *ps)
{
    if(ps->size==MAX)
    {
        printf("通讯录已满,无法增加");
    }
    else
    {
        printf("请输入名字:>");
        scanf("%s",ps->data[ps->size].name);//以%s的形式输入字符数组,引用时只写数组的名字
        printf("请输入年龄:>");
        scanf("%d",&(ps->data[ps->size].age));//注意不是数组形式时,要用&
        printf("请输入性别:>");
        scanf("%s",ps->data[ps->size].sex);
        printf("请输入电话:>");
        scanf("%s",ps->data[ps->size].tele);
        printf("请输入住址:>");
        scanf("%s",ps->data[ps->size].addr);
        ps->size++;
        printf("添加成功\n");
    }
}
int FindByName(const struct Contact *ps,char *name)
{
    int i=0;
    for(i=0;i<ps->size;i++)
    {
        if(0==strcmp(ps->data[i].name,name));//字符串比较不用==,0表示==
        {
            return i;
        }
    }
    return -1;//找不到
}
void Delcontact(struct Contact *ps)
{
    char name[MAX_NAME];
    printf("请输入要删除人的名字:");
    scanf("%s",name);
    //1.查找要删除的人的位置
    int pos=FindByName(ps,name);
    /*int i=0;
    for(i=0;i<ps->size;i++)
    {
        if(0==strcmp(ps->data[i].name,name));//字符串比较不用==,0表示==
        {
            break;
        }
    }删查改都要用到这一段,打包到一个FindBy函数里*/
    //2.删除
    if(-1==pos)
        printf("要删除的人不存在");
    else
    {
        int j=0;
        for(j=pos;j<(ps->size)-1;j++)
        {
            ps->data[j]=ps->data[j+1];
        }
        ps->size--;
        printf("删除成功");
    }
}
void SearchContact(const struct Contact *ps)
{
    char name[MAX_NAME];
    printf("请输入要查找人的名字:");
    scanf("%s",name);
    int pos=FindByName(ps,name);
    if(pos==-1) printf("要查找的人不存在");
    else
    {
        printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n","名字","年龄","性别","电话","住址");
        printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n",
                   ps->data[pos].name,
                   ps->data[pos].age,
                   ps->data[pos].sex,
                   ps->data[pos].tele,
                   ps->data[pos].addr);
    }
}
void ModifyContact(struct Contact *ps)
{
    char name[MAX_NAME];
    printf("请输入要修改人的名字");
    scanf("%s",name);
    int pos=FindByName(ps,name);
    if(pos==-1) printf("修改人的信息不存在");
    else
    {
        printf("请输入名字:>");
        scanf("%s",ps->data[pos].name);//以%s的形式输入字符数组,引用时只写数组的名字
        printf("请输入年龄:>");
        scanf("%d",&(ps->data[pos].age));//注意不是数组形式时,要用&
        printf("请输入性别:>");
        scanf("%s",ps->data[pos].sex);
        printf("请输入电话:>");
        scanf("%s",ps->data[pos].tele);
        printf("请输入住址:>");
        scanf("%s",ps->data[pos].addr);
        ps->size++;
        printf("修改完成\n");
    }
}
void Showcontact(const struct Contact *ps)//因为只是显示,为了避免误操作改变信息,加上const
{
    if(ps->size==0)
    {
        printf("通讯录为空");
    }
    else
    {
        int i=0;
        printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n","名字","年龄","性别","电话","住址");//加上负号,左对齐
        for(i=0;i<ps->size;i++)
        {
            printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",
                   ps->data[i].name,
                   ps->data[i].age,
                   ps->data[i].sex,
                   ps->data[i].tele,
                   ps->data[i].addr);
        }
    }
}
int main()
{
    int input=0;
    struct Contact con;/*int size=0;
                       //创建通讯录
                       struct PeoInfo con[MAX];*/
    //初始化通讯录
    InitContact(&con);
    do
    {
        menu();
        printf("请选择:>");
        scanf("%d",&input);
        switch(input)
        {
        case ADD:
            Addcontact(&con);
            break;
        case DEL:
            Delcontact(&con);
            break;
        case SEARCH:
            SearchContact(&con);
            break;
        case MODIFY:
            ModifyContact(&con);
            break;
        case SHOW:
            Showcontact(&con);//结构体传参传地址,效率更高,这个函数为了显示信息是否添加成功
            break;
        case SORT:
            break;
        case EXIT:
            printf("退出通讯录");
            break;
        default:
            printf("选择错误");
            break;
        }
    }while(input);
    return 0;
}

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值