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字节大小

  • 相关阅读:
    程序员:不要自称为码农
    SpringBoot对静态资源配置
    LeetCode 572. Subtree of Another Tree(子树)
    LeetCode 437. Path Sum III(统计路径和等于sum的路径数量)
    LeetCode 112. Path Sum(判断路径和是否等于一个数)
    LeetCode 617. Merge Two Binary Trees(归并两棵二叉树)
    LeetCode 226. Invert Binary Tree(翻转二叉树)
    Failure to transfer org.apache.maven.plugins:maven-resources-plugin:pom:2.6 的解决办法
    linux-查询某软件的安装的目录
    WebService概念解释
  • 原文地址:https://www.cnblogs.com/markstray/p/5603903.html
Copyright © 2011-2022 走看看