当前位置: 首页 > article >正文

C语言:构造类型(共用体/联合体,枚举)

共用体/联合体类型

定义

使几个不同的变量占用同一段内存的结构。共用体按定义中需要存储空间最大的成员来
分配存储单元,其他成员也是用该空间,他们的首地址是相同。

定义格式:

union 共用体名称
{
     数据类型 变量名;  -- 共用体成员
     数据类型 变量名;
     ...
};

公用体的定义和结构体类似:

        可以有名字,也可以匿名

        共用体在定义时也可以定义公用体变量

        共用体在定义时也可以初始化成员

        共用体也可以作为形参和返回值类型使用

        共用体也可以定义共用体变量

        ...

        也就是说,结构体的语法,共用体都支持

注意:

        共用体弊大于利,尽量少用,一般很少用;

        共用体变量在某一时刻只能存一个数据,并且也只能取出一个数

        共用体和结构体都是自定义数据类型,用法类似于基本数据类型

        共用体可以是共用体的成员,也可以是结构体的成员

        结构体可以是结构体的成员,也可以是共用体的成员

案例:

/**
 * 共用体
 */
#include <stdio.h>
// 定义共用体
union S
{
    char a;
    float b;
    int c;
};// 大小是4字节
// 共用体作为共用体的成员
union F
{
    char a;
    union S s; // 4字节
};// 大小是4字节
// 共用体作为结构体的成员
struct G
{
    int a;
    union S s;
};// 大小是8字节
// 定义一个结构体
struct H
{
    int a;
    char b;
};// 大小是8字节
// 结构体作为结构体成员
struct I
{
    int a; // 4
    int b; // 4
    struct H h; // 8
};// 大小是16字节
// 共用体作为结构体成员
struct J
{
    int a;// 4
    char b;// 1 + 3
    union S s;// 4
};// 大小是12字节
void test1()
{
// 定义共用体类型
    union Stu
   {
        int num;
        char sex;
        double score;
   };
    // 定义匿名共用体:匿名共用体一般作为结构体成员或者其他共用体成员
    union
   {
        int a;
        char c;
   } c;
    printf("%lu,%lu\n",sizeof(union Stu),sizeof(c));
}
void test2()
{
    union C
   {
        int a;
        char b;
   };
    
    // 定义变量
    union C c; 
    // 存数据
    c.a = 10;
    c.b = 'A';
    printf("%d---%d\n",c.a,c.b);// 取数据
    c.a += 5;
    printf("%d---%d\n",c.a,c.b);// 取数据
    union E
   {
        char *f;
        long a;
        int b;
   } e = {"hello world!"};
    printf("%s,%p---%ld,%p---%d\n",e.f,&(e.f),e.a,&(e.a),e.b);
}
int main()
{
    test1();
    test2();
}

枚举类型

定义

我们一般情况下,定义常量使用宏定义(#define 红名称值),宏定义非常适合没有关联关系的
常量;但是有时候我们可能需要对一组拥有关联关系的量进行定义,比如 ==周一~周日、1月~12
月、方向(上下左右中)等 ,那么使用宏定义,就不是很清晰,这个时候就需要使用到枚举。
枚举的存在就是将多个拥有关系的常量组合到一起,提高代码的可读性。

说明:

枚举类型定义了一组常量,我们在开发中直接使用这些常量。(常用)
当然枚举类型也可以类似于结构体一样定义变量等操作。(不常用)
枚举常量有默认值,从0开始依次+1;我们可以在定义时指定它的默认值,如果个别没有赋值,
可以根据赋值依次+1推导。

特点:

定义了一组常量,类似于定义了多个自定义常量(宏定义)
提供了代码的可读性。
定义语法:
定义枚举类型名以后就可以定义该枚举类型的变量。

enum 枚举类型名 变量列表;

在定义枚举类型的同时定义该枚举类型的变量。

enum 枚举类型名{枚举元素列表} 变量列表;

直接定义枚举变量

enum {枚举元素列表} 变量列表;

案例:

#include <stdio.h>
void test1()
{
 // 定义一个枚举类型
    // 枚举类型名一般首字母大写,主要是根枚举变量区分
    enum Week 
   {
       // 定义枚举元素,元素命名要符合标识符命名规则,同时采用大写字母+下划线方式命名
       SUN=10,MON,TUE,WED,THU,FRI,SAT
   };
    // 1.直接访问枚举元素
    printf("%d,%d,%d\n",SUN,WED,SAT);
    // 2.定义枚举类型的变量(先定义变量,后赋值)
    enum Week week;
    // 初始化
    week = TUE;// 一定是这个枚举类型中定义的元素
    printf("%d\n",week);
    // 3.定义枚举类型变量的同时赋值(定义变量和赋值同时进行)
    enum Week week1 = THU;
    printf("%d\n",week1);
    enum H
   {
        A,B,C // 多个元素使用逗号分隔
} x,y;
    x = B;
    y = C;
    printf("x=%d,y=%d\n",x,y);// 1,2
}
void test2()
{
 // 定义枚举
 enum CaiQuan
 {
 SHI_TOU,JIAN_DAO,BU
 };
 printf("请输入0~2之间的整数:\n[0-石头,1-剪刀,2-布]\n");
 int number;
 scanf("%d",&number);
 switch(number)
 {
 case SHI_TOU:
    printf("石头\n");
    break;
 case JIAN_DAO:
    printf("剪刀\n");
    break;
 case BU:
    printf("布\n");
    break;
 }
}
int main(int argc,char *argv[])
{
    test1();
 test2();
    return 0;
}

typedef

说明:给类型重命名,不会影响到类型本身
作用:给已有的类型起别名
格式:

typedef 已有类型名 新别名;

使用:

// 方式1:先定义结构体类型,再重命名
// 定义一个结构体类型
struct Student
{
    int id;
    char *name;
    char sex;
    int age;
};
// 类型重命名
typedef struct Student Stu;
// 定义结构体变量
struct Stu stu = {1,"张三",'w',21};
// 方式2:定义结构体的同时重命名
typedef struct PersonInfo
{
    int a;
    double b;
} Per; // 结构体类型的别名,本质上还是数据类型
// 定义变量
struct Per per = {2,5};

应用场景:

数据类型复杂(结构体、共用体、枚举、结构体指针、无符号的长整型)时使用
为了跨平台兼容性,例如:
1. size_t:类型重命名后的数据类型: typedef unsigned long size_t;

2. unit_16:类型重命名后数据类型

案例:

//类型重命名
#include <stdio.h>
struct Student
{
    int age;
    char* name;
    double score;
    int arr[3];
};
typedef struct Student  Stu_t;// 数据类型重命名
typedef Stu_t* pStu_t;// 结构体指针重命名
void test1()
{
    Stu_t s1 = {23, "zhangsan", 23.33, {11, 22, 33}};
    printf("%d, %s, %f, %d\n", s1.age, s1.name, s1.score, s1.arr[0]);
    
    //Stu_t *p = &s1;
    Stu_t*  p;
    p = &s1;
    pStu_t p2;
    p2 = p;
    printf("%d, %s, %f, %d\n", p2->age, p2->name, p2->score, p2->arr[0]);
    
}
int main()
{
    test1();
    return 0;
}


http://www.kler.cn/a/488306.html

相关文章:

  • Transformer入门教程全解析(一)
  • 如何设计一个注册中心?以Zookeeper为例
  • sql server cdc漏扫数据
  • Linux 系统下磁盘相关指令:df、du、fdisk、lsblk
  • C++实现图书管理系统(Qt C++ GUI界面版)
  • ubuntu22.04 的录屏软件有哪些?
  • Apache AGE:基于PostgreSQL的图数据库深度解析
  • Python--正则表达式
  • HarmonyOS开发:粒子动画应用实战
  • pytest 常用插件
  • Redis数据库笔记——Redis快的原因
  • Java(day7)
  • HTTP 与 HTTPS 网络传输
  • Linux -- 初步了解 TCP 编程
  • ubuntu 20.04 安装 5.4 内核
  • CClinkIEfield Basic转Modbus TCP网关模块连接三菱FX5U PLC
  • 关于物联网的基础知识(四)——国内有代表性的物联网平台都有哪些?
  • xml-dota-yolo数据集格式转换
  • 【FPGA】时序约束与分析
  • 部署langchain服务
  • 使用 FastAPI 和 Async Python 打造高性能 API
  • 超大规模分类(三):KNN softmax
  • cJson——序列化格式json和protobuf对比
  • 单元测试MockitoExtension和SpringExtension
  • poi处理多选框进行勾选操作下载word以及多word文件压缩
  • Cognitive architecture 又是个什么东东?