zoukankan      html  css  js  c++  java
  • C 碎片八 结构体&枚举&联合

    一、结构体

    1, 结构体定义

    结构体类型的定义:任意数据类型变量的集合。用于描述一个具体的事物的信息,C语言中描述一件事物一般都是用结构体

    声明结构体类型的格式: struct  结构体名 {成员列表}; 

    一般形式:

    //结构体定义一般形式
     struct 结构体名 {
        成员变量1; //成员变量后面是';'
        成员变量2; 
        .... 
    };
    //这里最后加';' 不能省略

      

    例:

    struct Student {
        char name[30]; 
        int age;
        double score;
    };
    

    说明:

      1. 先定义一个结构体类型 (结构体类型要先定义再使用)

      2. 上面结构体用于描述一个学生的信息,表示一个学生: 姓名 年龄 分数

      3. 结构体类型一般定义在函数外面

     

    2, 结构体变量声明

    结构体类型  struct Student . int char long double  int * 等等 都是一样的,都只是一个数据类型而已,声明变量的时候和之前变量声明的格式是一样的

    struct Student xiaohong;
    

    说明:定义一个结构体变量,表示一个学生小红

     

    3, 结构体访问/操作

    //用 '.'操作/访问 结构体变量中的成员
        
    //结构体变量名.成员变量名 --->访问指定的成员
        
    //访问年龄 对结构体变量xiaofen中age赋值
    xiaofen.age = 24;//得到了age 变量名
    
    //对分数赋值
    xiaofen.score = 100;//得到了score变量名
    
    //对名字赋值
    //xiaofen.name = "xiaofen";
    //错误的xiaohong.name 得到了一个数组名 ,数组名是一个常量不能赋值
        
    //用字符串拷贝
    strcpy(xiaohong.name, "xiaohong");
    

      

    4, 结构体初始化

    //结构体的初始化
    //结构体变量的初始化 要对里面的每个成员初始化
    struct Student xiaohong = {"xiaohong",24,90.0};
    

    5, 结构体整体赋值

    //结构体变量可以整体赋值
    struct Student x;
    
    //把xiaohong 变量里面的所有成员依次赋给 x结构体变量
    x = xiaohong;
    

      

    6, 结构体的变种

    上面的前三步操作是"先定义结构体类型再定义变量",下面是其他形式:

    1. 声明类型的同时定义变量

    struct Student {
        char name[30]; 
        int age;
        double score;
    }xiaohuang,xiaogang;
    

    说明:定义结构体Student 同时定义了两个struct Student类型的变量xiaohuang,xiaogang。也可以用 struct Student xxx 来定义结构体变量;

    2. 直接定义结构体类型变量

    struct {
        char name[30]; 
        int age;
        double score;
    }xiaohuang,xiaogang;
    

    说明:区别没有出现结构体名。定义结构体Student 同时定义了两个struct Student类型的变量xiaohuang,xiaogang。不能用 struct Student xxx 来定义结构体变量;

    3. typedef重命名变种

    直接重命名,使用没有区别

    //定义结构体类型
    typedef struct Student {
        char name[30]; 
        int age;
        double score;
    }GoodStudent;
    
    //声明结构体变量
    GoodStudent xiaohong;
    

    间接重命名,使用没有区别

    //定义结构体类型
    struct Student {
        char name[30]; 
        int age;
        double score;
    };
    
    //typedef起别名
    typedef Student GoodStudent;
    
    //声明结构体变量
    GoodStudent xiaohong;
    

      

    7, 结构体指针

    结构体也可以有指针类型,叫做结构体指针。定义个结构体指针,指向一个结构体变量就可以用结构体指针来操作这个变量

    //定义一个结构体变量xiaohong并初始化
    struct Student xiaohong;
    xiaohong.age = 24;
    xiaohong.score = 100;
    strcpy(xiaohong.name, "xiaohong");
    
    //定义一个结构体变量指针变量 指向结构体变量xiaohong
    //*p  表示p指向的空间  这里就是结构体变量xiaohong
    struct Student * p = &xiaohong;
    
    /*结构体指针操作 修改*/
    
    //.的优先级高于 * : *p是一个整体表示结构体空间,所以要加()
    (*p).age = 25;
    (*p).score = 120;
    
    //结构体指针 可以用->直接访问结构体成员
    p->age = 26;//p->age  就是变量age
    p->score = 100;
    strcpy(p->name, "xiaohuang");//p->name 就是name数组名
    

     

    8, 结构体类型的说明

    1. 类型与变量是不同的概念。我们只能对变量赋值、存取、运算,不能对类型进行操作;编译时,对类型是不分配空间的,只对变量分配空间,不仅适用于结构体,所有数据类型都是如此,包括对象。

    2. 对结构体中的成员可以单独使用,使用方法及作用和普通变量是一样一样的

    3. 结构体成员可以是结构体类型,在进行操作的时候需要一级一级找到最低的一级的成员(普通类型)

    4. 结构体成员可以数组,在初始化的时候需要对数组中的每个元素进行初始化

    5. 不能将一个结构体作为一个整体输入输出

    6. 结构体可以作为函数参数以及返回值

    7. 可以引用结构体成员的地址,也可以引用结构体变量的地址

      &xiaohong.age  表示结构体成员age的地址

      &xiaohong  表示结构体变量的地址

    二、枚举

    1, 枚举定义

    枚举类型的定义:将变量的值一一列举出来。如果一个变量只有几种可能的值则可以定义为枚举类型,变量的值只限于列举的值的范围内,使用枚举可以增强代码可读性

    声明枚举类型的格式: enum  枚举名 {枚举常量列表}; 

    一般形式:

    //枚举定义一般形式
    enum 枚举名 {
        枚举常量1, //后面加 ‘,’
        枚举常量2, //最后一个成员 可以不加','
        ...
    };
    //这里最后加';' 不能省略
    

    2, 先定义枚举类型再声明枚举变量

    //定义枚举类型
    enum Sex {
        Male,
        Female,
        NoneSex 
    };
    
    //声明枚举变量
    enum Sex xiaomingSex;
    
    //typedef 重新定义 enum Sex 类型
    typedef enum Sex MySex;
    
    //再次声明枚举变量
    MySex xiaohongSex;
    

    说明:一旦定义 枚举类型 之后,那么enum Sex 类型和里面的Male、Female、NoneSex枚举常量在下面就可以直接使用了。Male表示的是整型数字0,Female表示的是整型数字1,NoneSex表示整形数字2。默认情况下,第一个枚举常量表示0,后面的依次加1;如果指定Female为3,则Female前面的枚举常量默认从0开始,后面的枚举常量为当前值+1,也就是Male为0,NoneSex为4。

     

    3, 定义枚举类型同时声明枚举变量

    //定义枚举类型
    enum Sex {
        Male,
        Female,
        NoneSex 
    }xiaomingSex;
    
    //typedef 重新定义 enum Sex 类型
    typedef enum Sex MySex;
    
    //再次声明枚举变量
    MySex xiaohongSex;
    

    4, 枚举类型的说明

    1. 在C编译中,对枚举按照常理处理,故称枚举常量。因为不是变量,所以不能对其赋值,即不能Male=100

    2. 枚举元素作为常理,是有值的,C语言编译按照定义时的顺序使他们的值为0,1,2,。。。

    3. 枚举值可以用来做判断

    4. 枚举的作用是增强代码的可读性

    三、联合

    1, 联合体类型定义

    联合体类型的定义:使用覆盖技术,使几个变量互相覆盖占用同一段内存的结构类型,也叫共用体类型

    声明联合体类型的格式: union  联合体名 {成员列表}; 

    一般形式:

    //联合定义一般形式
    union Test {
        成员变量1; //成员变量后面是';'
        成员变量2; 
         ....
    };//这里最后加';' 不能省略

     

    2, 先定义联合类型再定义联合变量

    //定义联合类型
    union Test {
        int x;
        char y;
        double z;
    };
    
    声明联合变量 aTest
    union Test aTest;
    
    //typedef 重新定义 union Test 类型
    typedef union Test MyTest;
     
    //声明联合变量bTest
    MyTest bTest;

    说明:联合的成员 是共享同一个内存空间,以成员中最大数据类型作为空间的大小,上面的类型大小是8(double占8字节),x、y、z 共享同一个空间

     

    3, 定义联合类型同时声明联合变量

    //定义联合类型
    union Test {
        int x;
        char y;
        double z;
    }aTest; 

    //typedef 重新定义 union Test 类型
    typedef union Test MyTest;

    //声明联合变量bTest
    MyTest bTest;

    4, 联合类型的说明

    1. 同一内存段可以用来存放不同类型的成员,但在每一瞬间只能存放其中的一种,也即在同一瞬间只有一个成员起作用,不是同时存在和起作用的

    2. 联合体变量中起作用的成员是最后一次存放的成员,存放一个新的成员后原有的成员就失去作用

    3. 联合体变量的地址和它各成员的地址都是同一地址。&aTest,&aTest.x,&aTest.y,&aTest.z,都是同一地址

     

    5, 联合类型证明电脑存储方式 

    存储数据分为:大端存储  小端存储

    大端:存储数据时,把数据的高字节放在低地址  把低字节放在高地址

    小端:存储数据时,把数据的高字节放在高地址  把低字节放在低地址

    // 1004          1003          1002         1001
    // |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|
    //     12          34         56         78
    
    //高       低字节
    //0x12345678
    
    union Test a;
    a.x = 0x12345678;
    a.y = 0x00;
    
    printf("a.x : %#x
    ",a.x);//0x12345600
    printf("a.y : %#x
    ",a.y);//0
    
    //结论:我们的电脑是大端存储

    实现一个函数:证明你的电脑是大端还是小端 

    // 1004          1003          1002         1001
    // |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|
    //     00          00         00         01
    
    int isLittleEndian(void) {
        union Test a;
        a.x = 1;
    
        /* method 1
        if (a.y) {
            return 1;
        }else{
            return 0;
        }*/
        
        //method 2
        return a.y;
    
        //method 3
        return  *((char *)&a);//对指针强转 取第一个字节
    }
    
    // 调用函数 true 小端; false 大端
    

    四、位段

    1, 位段定义:C语言允许在结构体中以位为单位制定成员所占内存长度,这种方式称为"位段","位域","位字段"。功能是用较少的位数储存数据,节省空间。实质就是一个结构体类型, 成员变量的类型只能是unsigned char,unsigned int,unsigned long;每个成员变量后加一个数字,表示这个变量在空间占多少位。

    struct Word {
        //字体大小
        unsigned int size:7;//size 变量的空间占7位
        //字体的类型
        unsigned int style:7;//占7位
        //粗细
        unsigned int blod:1;//占1位
        //字体颜色
        unsigned int color:8;//占8位
    };
    

    说明:

      1. 上面的位段所有的成员变量只需要 23位就可以了

      2. 结构体考虑对齐所以上面的类型大小4字节大小

  • 相关阅读:
    一个小案例精通lamda表达式
    你想被开除吗?来看看程序员【离职小技巧】吧
    让 Flutter 在鸿蒙系统上跑起来
    “TensorFlow 开发者出道计划”全攻略,玩转社区看这里!
    环形单链表的增删改查、约瑟夫环两种解法
    一万字详解 Redis Cluster Gossip 协议
    Lambda表达式
    Linux系统中如何进入退出vim编辑器,方法及区别
    成为博客主的第一天
    【秋招内推】近期互联网公司秋招内推合集
  • 原文地址:https://www.cnblogs.com/markstray/p/5603903.html
Copyright © 2011-2022 走看看