结构体、共用体/联合体、枚举、typedef详解

师承clc

初始

为什么要用结构体

整型数,浮点型数,字符串是分散的数据表示,有时候我们需要用很多类型的数据来表示一个整体,比如学生信息

类比与数组:数组是元素类型一样的数据集合,如果是元素类型不同的数据集合,就要用到结构体了

定义一个结构体

它算是一个模板,一般不给赋具体的值,每一项在实际应用中并不是都要使用

成员列表

也称为域表--每个成员都是结构体中的一个域

在声明的同时,定义变量,尽量少用

初始化一个结构体变量并引用

  • 初始化
  • 引用

重点认知

结构体没什么特殊的,只是把变量藏在结构体里面,而内部的变量,以前学习的东西是通用的,只是“触达的方式”不同

例题

输入两个学生的名字,学号,成绩,输出成绩高的学生的信息

#include <stdio.h>

struct Student
{
    char name[12];
    int num;
    int sor;
};
int main()
{
    struct Student stu[1];
    struct Student max;
    
    max = stu[0];
    
    for(int i=0;i<2;i++){
        printf("输入第%d个学生名字:\n",i+1);
        scanf("%s",&(stu[i].name));
        printf("输入第%d个学生学号:\n",i+1);
        scanf("%d",&(stu[i].num));
        printf("输入第%d个学生分数:\n",i+1);
        scanf("%d",&(stu[i].sor));
    }
    if(stu[0].sor < stu[1].sor){
        max = stu[1];
    }
    printf("成绩最高的学生名字是:%s,成绩是%d\n",max.name,max.sor);
    return 0;
}

结构体数组

应用练习:选票系统

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

struct XuanMin
{
    char name[12];
    int tickets;
};
int main()
{
    int i,j;
    int n = 1;
    int totalPer;
    int totalTic;
    int mark;
    int feipiao = 0;
    char tempName[12] = {'\0'};
    
    printf("请输入参选人数:\n");
    scanf("%d",&n);
    
    struct XuanMin xm[n-1];
    struct XuanMin max;

    printf("请输入参加投票人数:\n");
    scanf("%d",&totalPer);
    
    for(i=0;i<n;i++){
        printf("请输入第%d个选名的名字",i+1);
        scanf("%s",xm[i].name);
        xm[i].tickets = 0;
    }
    
    for(j=0;j<totalPer;j++){
        
        mark = 0;
        printf("请输入你投给谁:\n");
        memset(tempName,'\0',sizeof(tempName));
        scanf("%s",tempName);
        for(i=0;i<n;i++){
            if(strcmp(tempName,xm[i].name) == 0){
                xm[i].tickets++;
                mark = 1;
            }
        }
        if(mark == 0){
            printf("没有此人,此票作废\n");
            feipiao++;
        }
    }
    
    for(i=0;i<n;i++){
        printf("名字:%s,票数:%d \n",xm[i].name,xm[i].tickets);
    }
    max = xm[0];
    for(i=0;i<n;i++){
        if(max.tickets < xm[i].tickets){
            max = xm[i];
        }
    }
    
    printf("%s 以 %d 票当选,废票是 %d 票\n",max.name,max.tickets,feipiao);
    return 0;
}

结构体指针

概念引入

回忆:

指针就是地址,指针变量就是存放地址的变量,结构体也是变量,变量访问有两种方式 : 1.变量名 2.地址

之前案例,是用变量名访问

通过结构体变量地址来访问该结构体,需要一个变量来保持这个地址:,这和之前说的指针,其实是一样的,只是指针类型是结构体

通过结构体指针访问结构体

结构体数组,指针,函数应用

根据选票系统进行修改
#include <stdio.h>
#include <string.h>

struct XuanMin
{
    char name[12];
    int tickets;
};

int main()
{
    int i,j;
    int n = 1;
    int totalPer;
    int totalTic;
    int mark;
    int feipiao = 0;
    char tempName[12] = {'\0'};
    
    printf("请输入参选人数:\n");
    scanf("%d",&n);
    
    struct XuanMin xm[n-1];
    struct XuanMin max;
    struct XuanMin *p;
    p = xm;
    
    printf("请输入参加投票人数:\n");
    scanf("%d",&totalPer);
    
    for(i=0;i<n;i++){
        printf("请输入第%d个选名的名字",i+1);
        scanf("%s",p->name);
        p->tickets = 0;
        p++;
    }
    p = xm;
    for(j=0;j<totalPer;j++){
        
        mark = 0;
        printf("请输入你投给谁:\n");
        memset(tempName,'\0',sizeof(tempName));
        scanf("%s",tempName);
        p = xm;
        for(i=0;i<n;i++){
            if(strcmp(tempName,p->name) == 0){
                p->tickets++;
                mark = 1;
            }
            p++;
        }
        if(mark == 0){
            printf("没有此人,此票作废\n");
            feipiao++;
        }
    }
    p = xm;
    for(i=0;i<n;i++){
        printf("名字:%s,票数:%d \n",p->name,p->tickets);
        p++;
    }
    p = xm;
    max = xm[0];
    for(i=0;i<n;i++){
        if(max.tickets < p->tickets){
            max = xm[i];
            p++;
        }
    }
    
    printf("%s 以 %d 票当选,废票是 %d 票\n",max.name,max.tickets,feipiao);
    return 0;
}
选民系统小综合(函数)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct XuanMin
{
    char name[12];
    int tickets;
};

struct XuanMin* initXM(struct XuanMin *p,int *pn, int *ptotalPer)
{
    if(p == NULL){
        printf("请输入有几人参选:");
        scanf("%d",pn);
        p = (struct XuanMin*)malloc(*pn * sizeof(struct XuanMin));
    }
    printf("请输入参加投票人数:\n");
    scanf("%d",ptotalPer);
    
    for(int i=0;i<*pn;i++){
        printf("请输入第%d个选名的名字",i+1);
        scanf("%s",p->name);
        p->tickets = 0;
        p++;
    }
    return p-*pn;
}

void printfXM(struct XuanMin *p,int n)
{
    for(int i=0;i<n;i++){
        printf("名字:%s,票数:%d \n",p->name,p->tickets);
        p++;
    }
}

int doVot(struct XuanMin *p,int totalPer,int n)
{
    int i;
    int j;
    int mark;
    int feipiao = 0;
    char tempName[12] = {'\0'};
    struct XuanMin *pbak = p;
    for(j=0;j<totalPer;j++){
        
        mark = 0;
        printf("请输入你投给谁:\n");
        memset(tempName,'\0',sizeof(tempName));
        scanf("%s",tempName);
        p = pbak;
        for(i=0;i<n;i++){
            if(strcmp(tempName,p->name) == 0){
                p->tickets++;
                mark = 1;
            }
            p++;
        }
        if(mark == 0){
            printf("没有此人,此票作废\n");
            feipiao++;
        }
    }
    return feipiao;
}

struct XuanMin* getMax(struct XuanMin *p,int n)
{
    struct XuanMin    *max;
    int i;
    max = p;
    for(i=0;i<n;i++){
        if(max->tickets < p->tickets){
            max = p;
        }
        p++;
    }
    return max;
}
int main()
{
    int n = 0;
    int totalPer;
    int totalTic;
    struct XuanMin *final;
    struct XuanMin *xm = NULL;
    
    xm = initXM(xm,&n,&totalPer);
    
    int feip = doVot(xm,totalPer,n);
    printfXM(xm,n);
    
    final = getMax(xm,n);
    printf("%s 以 %d 票当选!!,废票数是 %d \n",final->name,final->tickets,feip);
    return 0;
}
选民系统改进(二级指针版)
struct XuanMin* initXM(struct XuanMin **p,int *pn, int *ptotalPer)
{
    if(*p == NULL){
        printf("请输入有几人参选:");
        scanf("%d",pn);
        *p = (struct XuanMin*)malloc(*pn * sizeof(struct XuanMin));
    }
    printf("请输入参加投票人数:\n");
    scanf("%d",ptotalPer);
    
    for(int i=0;i<*pn;i++){
        printf("请输入第%d个选名的名字",i+1);
        scanf("%s",(*p)->name);
        (*p)->tickets = 0;
        (*p)++;
    }
    (*p) = (*p) - *pn;
}

initXM(&xm,&n,&totalPer);

//其他代码无改动

共用体/联合体

概念引入

  • 有时候同一个内存空间存放类型不同,不同类型的变量共享一块空间

  • 结构体元素有各自单独空间,共用体元素共享空间,空间大小由最大类型确定

  • 结构体元素互不影响,共用体赋值会导致覆盖

注意数据覆盖

应用

枚举类型

什么是枚举类型

  • 如果一个变量只有几种可能的值,比如星期几son mon tus wed thu fri sat

怎么定义枚举类型
  • 列表中的名字,可以自己定义,无需像变量一样去申请

  • C编译器把它当成常量处理,也称枚举常量

枚举变量

只限列表中的集中情况
值默认从0开始,枚举元素不能被赋值,虽然瞅着象变量名
可以指定列表中枚举数的值
可以直接忽略枚举类型名,直接定义枚举变量
例子

typedef关键字

  • 给已经有的变量类型起名字

  • 一般配合结构体用,方便嘛,不要每次都要struct开头

案例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值