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

C 语言学习笔记(结构体1)

内容提要

  • 构造类型
    • 结构体
    • 共用体/联合体

构造类型

数据类型

1.基本类型/基础类型

  • 整型

    • 短整型:short[int] – 2字节

    • 基本整型:int – 4字节

    • 长整型:long – 32位系统4字节/64位系统8字节

    • 长长整型:long log[int] – 8字节(大多数现代机器,旧机器可能超过8字节),C99新增

      注意:以上类型又都分为signed(默认)和unsigned

  • 浮点型

    • 单精度型:float – 4字节
    • 双精度型:double – 8字节
    • 长双精度型:long double – C99新增
  • 字符型:char – 1字节

2.指针类型

  • 数据类型*:int* char* float*等 --32位系统4字节/64位系统8字节
  • void*:通用类型指针(万能指针)-- 32位系统4字节/64位系统8字节

3.空值类型

  • void:无返回值,无形参(不能定义变量

4.构造类型(自定义类型)

  • 结构体类型:struct
  • 共用体/联合体类型:union
  • 枚举类型:enum

结构体

结构体定义【定义类型】
  • 定义:自定义数据类型的一种,关键字struct,结构体类型的变量可以出处多个不同数据类型的数据。

  • 语法

    struct 结构体名 // 我们定义的数据类型的名字
    {数据类型1 成员名称1; // 结构体中的变量叫做成员数据类型2 成员名称2;...
    };
    

    注意:结构体中定义的变量,称之为成员变量(成员属性)

  • 格式说明

    • 结构体名:合法的表示符,建议首字母大写(所谓的结构体名,就是自定义类型的类型名称)
    • 数据类型n:C语言支持的所有类型(包括函数,函数在这里用函数指针表示)
    • 成员名称n:合法的表示,就是变量的命名标准
    • 数据类型n成员名称n:类似于定义变量,定义了结构体中的成员
  • 注意

    • 结构体在定义的时候,成员不能赋值,示例:
    struct Cat
    {int age = 5;      // 错误,结构体定义的时候,成员不能赋值double height;    // 正确void (*run)(void) // 正确
    }
    
  • 常见的定义格式

    • 方式1:常规定义(命名结构体,只定义数据类型)
    struct Student
    {int num;        // 学号char name[20];  // 姓名char sex;       // 姓名int age;        // 年龄char address[100]; // 籍贯void(*info)(void); // 信息输出(函数指针)
    }
    
    • 方式2:匿名结构体(产用于其他结构体的成员使用)
    struct Dog
    {char *name;    // 姓名int age;       // 年龄// 匿名结构体struct{// 定义结构体是不能省略成员int year;   // 年int month;  // 月int day;    // 日}birthday;      // 生日,匿名结构需要提供成员名称,否则无法访问
    }
    

    注意:定义匿名结构体的同时必须定义结构体成员,否则编译报错;结构体可以作为另一个结构体的成员

    总结:

    • 结构体可以定义在局部位置(函数作用域、块作用域),也可以定义在全局位置(推荐,可以复用)
    • 全局位置的结构体名和局部位置的结构体名可以相同,遵循就近原则(和变量的定义同理)
  • 结构体类型的使用

    利用结构体类型定义变量、数组,也可以作为函数的返回值和参数;结构体类型的使用与基本数据类型的使用类似。

结构体变量定义【定义变量】
三种形式定义结构体变量

说明结构体变量也被称之为结构体实施。

  • 第1种

    ① 先定义结构体(定义数据类型)

    ② 然后定义结构体变量(定义变量)

    示例:

    // 定义结构体(定义数据类型)
    struct A
    {int a;char b;
    };// 定义结构体实例(定义变量)
    struct A x; // A就是数据类型,x就是变量名
    struct A y; // A就是数据类型,y就是变量名
    
  • 第2种

    ① 在定义结构体的同时,定义结构体变量(同时定义数据类型和变量)

    语法:

    struct 结构体名
    {  数据类型1 数据成员1;...
    } 变量列表;
    

    示例:

    struct A
    {int a;char b;
    } x,y; // A就是数据类型,x,y就是变量名
    

    此时定义了一个结构体A,x和y是这个结构体类型的变量。

  • 第3种

    ① 在定义匿名结构体的同时,定义结构体变量。

    struct
    {int a;char b;
    } x,y;
    

    此时定义了一个没有名字的结构体(匿名结构体),x和y是这个结构体类型的变量。

匿名机构体
  • 优点:少写一个结构体名称
  • 缺点:只能使用一次,定义结构体类型的同时必须定义变量。
  • 应用场景:
    • 当结构体的类型只需要使用一次,并且定义类型的同时定义了变量。
    • 作为其他结构体的成员使用。
定义结构体同时变量初始化

说明:定义结构体的同时,定义结构体变量并初始化

struct Cat
{int age;char color[20];
}cat;
  • 结构体成员部分初始化,大括号不能省略
  • 结构体成员,没有默认值,都是随机值,和局部作用域的变量一致。

案例:

/**
* 先定义结构体,再定义结构体变量(实例)
*/
void fun1()
{// 定义结构体struct A{int a;char b;};// 定义结构体变量struct A x;struct A y;struct A x1, y1;
}/**
* 定义结构体的同时定义结构变量
*/
void fun2()
{struct A{int a;char b;} x,y;struct A Z;struct A x1,y1;
}/**
* 定义结构体的同时定义结构体变量
*/
void fun3()
{struct{int a;char b;} x,y;struct{int a;char b;} z;
}int main(int argc,char *argv[])
{fun1();fun2();fun3();return 0;
}
结构体变量的使用【变量存取】
结构体变量访问成员
  • 语法

    结构体变量名(示例名), 成员名;
    

    ① 可以通过访问给成员赋值(存数据)

    ② 可以通过访问获取成员的值(取数据)

  • 结构体变量未初始化,结构体成员的值随机的(和局部作用域的变量和数组同理)

结构体变量定义时初始化
  • 建议用大括号{}标明数据的范围

  • 结构体成员初始化,可以部分初始化(和数组类似),部分初始化石一定要带大括号标明

  • 案例

    /* 定义全局的结构体,方便复用 */
    struct Dog
    {char *name;        // 名字int age;           // 年龄char sex;          // M:公,W:母void (*eat)(void); // 吃狗粮
    };void eat()
    {printf("够够在吃狗粮!\n");
    }/**
    * 方式1:先定义,再初始化 ---> 结构体变量访问成员
    */
    void fun1()
    {// 定义结构体变量struct Dog dog;// 给结构体变量成员赋值dog.name = "大黄";dog.age = 5;dog.sex = 'M';dog.eat = eat;// 结构体变量成员访问printf("%s,%d,%c\n", dog.name, dog.age, dog.sex);// 访问成员方法(函数)dog.eat();
    }/**
    * 方式2:定义的同时初始化 ---> 结构体变量定义时初始化
    */
    void fun2()
    {// 定义结构体变量的同时,给变量成员初始化struct Dog dog = {"旺财"5'M', eat};// 修改成员的值dog.name = "金宝";// 访问结构体变量成员printf("%s.%d.%c\n", dog.name, dog.age, dog.sex);// 访问成员方法(函数)dog.eat();
    }int main(int argc,char *argv[])
    {fun1();fun2();return 0;
    }
    

    扩展版:给函数指针指向的函数,绑定了参数

    /* 定义全局的结构体,方便复用 */
    struct Dog
    {char *name;        // 名字int age;           // 年龄char sex;          // M:公,W:母void (*eat)(void); // 吃狗粮
    };void eat()
    {printf("够够在吃狗粮!\n");
    }/**
    * 方式1:先定义,再初始化 ---> 结构体变量访问成员
    */
    void fun1()
    {// 定义结构体变量struct Dog dog;// 给结构体变量成员赋值dog.name = "大黄";dog.age = 5;dog.sex = 'M';dog.eat = eat;// 结构体变量成员访问printf("%s,%d,%c\n", dog.name, dog.age, dog.sex);// 访问成员方法(函数)dog.eat(dog.name);
    }/**
    * 方式2:定义的同时初始化 ---> 结构体变量定义时初始化
    */
    void fun2()
    {// 定义结构体变量的同时,给变量成员初始化struct Dog dog = {"旺财"5'M', eat};// 修改成员的值dog.name = "金宝";// 访问结构体变量成员printf("%s.%d.%c\n", dog.name, dog.age, dog.sex);// 访问成员方法(函数)dog.eat(dog.name);
    }int main(int argc,char *argv[])
    {fun1();fun2();return 0;
    }
    
结构体数组的定义【数组定义】
什么时候需要结构体数组

比如:我们需要管理一个学生对象,只需要定义一个struct Student zhangsan

例如:我们需要管理一个班的学生对象,此时就需要定义一个结构体数组struct Student stus[50];

四种形式定义结构体数组
  • 第1种:结构体 → 结构体变量 → 结构体数组,举例:
// 定义一个学生结构体(定义数据类型)
struct Student
{char *name;      // 姓名int age;         // 年龄float scores[3]; // 三门课程的成绩
};// 定义结构体变量/示例
struct Student zhangsan = {"张三"21{88,89,78}}struct Student lisi = {"李四"22{66,78,98}}// 定义结构体数组
struct Student stus[3] = {zhangsan, lisi};
  • 第2种:结构体 → 结构体数组,举例:
// 定义一个学生结构体(定义数据类型)
struct Student
{char *name;      // 姓名int age;         // 年龄float scores[3]; // 三门课程的成绩
};// 定义结构体数组并初始化
struct Student stus[3] = {{"张三"21{88,89,78}};{"李四"22{66,78,98}}
};
  • 第3种:结构体与数组一体化(含初始化),举例:
// 定义一个学生结构体数组,并初始化
struct Student
{char *name;      // 姓名int age;         // 年龄float scores[3]; // 三门课程的成绩
}stus[3] = {{"张三"21{88,89,78}};{"李四"22{66,78,98}}
};
  • 第4种:结构体与数组一体化(不含初始化),举例:
// 定义一个学生结构体数组
struct Student
{char *name;      // 姓名int age;         // 年龄float scores[3]; // 三门课程的成绩}stus[3];// 赋值
suts[0].name = "张三";
suts[0].age = 21;
suts[0].scores[0] = 88;
suts[0].scores[1] = 89;
suts[0].scores[2] = 78;suts[1].name = "李四";
suts[1].age = 22;
suts[1].scores[0] = 66;
suts[1].scores[1] = 78;
suts[1].scores[2] = 98;
结构体数组的访问【数组访问】

语法

结构体指针 -> 成员名

举例

// 方式1:普通的指针访问
(*p).成员名
// 方式2:结构体指针访问(结构体指针访问符号 ->),等价与上面写法
p -> 成员名

例子

/* 定义全局的Student结构体 */
struct Student
{int id;                  // 编号char *name;              // 名字int age;                 // 年龄float scores[3];         // 三门成绩void (*info)(char*,int); // 信息输出
};/**
* 定义一个函数,实现信息输出
*/
void info(char* name, int age)
{printf("大家好,我是%s,今年%d岁!\n", name, age);
}int main()
{// 定义结构体实例并初始化struct Student zhangsan = {1, "张三"21{78,88,98}, info}struct Student lisi     = {2, "李四"22{78,88,98}, info}// 定义结构体数组并初始化struct Student stus[] = {zhangsan,lisi};// 计算数组的大小int len = sizeof(stus) / sizeof(stus[0]);// 指针法遍历数组struct Student *p = stus;// 表格-表头printf("序号\t姓名\t年龄\t语文\t数学\t英语\t\n")for (; p < stus + len; p++){/*  普通指针的访问,不推荐printf("%d\t%s\t%d\t%.2f\t%.2f\t%.2f\t\n", (*p).id, (*p).name, (*p).age, (*p).scores[0], (*p).scores[1], (*p).scores[2]);(*p).info(*p.name, (*p).age);      */// 结构体指针访问printf("%d\t%s\t%d\t%.2f\t%.2f\t%.2f\t\n", p -> id, p -> name, p -> age, p -> scores[0], p -> scores[1], p -> scores[2]);p -> info(p -> name, p -> age); }printf("\n");return 0;
}

注意:当 -> []共存的时候,他们的优先级关系:[] > ->

结构体类型

结构体数组
案例:
  • 需求:对候选人得票的统计程序。设有3个候选人,每次输入一个得票的候选人名字,要求最后输出各人得票的结果。
  • 代码:
#include <stdio.h>
#include <string.h>/**
* 定义一个候选人结构体
*/
struct Person
{char name[20];    // 名字int count;        // 票数
};/**
* 定义候选人数组,并初始化
*/
struct Person persons[] = {{"张三", 0},{"李四", 0},{"王五"0}
};int main()
{// 定义循环变量int i, j;// 创建一个数组,用来接收控制台录入的候选人名字char leader_name[20];// 使用一个for循环,模拟10个人投票for(i = 0; i < 10; i++){printf("请输入您要投票的候选人姓名:\n");scanf("%s, leader_name");// 从候选人列表中匹配被投票的人 +1票for(j = 0; j < sizeof(persons) / sizeof(persons[0]); j++){// 判断两个字符串 strcmpif(strcmp(leader_name, persons[j].name) == 0){persons[j].count++;}}}printf("\n投票结果:\n");// 遍历数组:指针法struct Person *p = persons;for(;p < persons + 3; p++){// printf(" %s:%d\n",(*p).name,(*p).count);printf(" %s:%d\n",p -> name,p -> count);}pritnf("\n");// 遍历数组:指针法for(i = 0; i < 3; i++){printf(" %s:%d\n",(persons + i) -> name, (persons + i) -> count);}pritnf("\n");// 遍历数组:下标法for(i = 0; i < 3; i++){printf(" %s:%d\n",persons[i].name, persons[i].count);}pritnf("\n");return 0;
}
结构体指针
  • 定义结构体类型的指针变量指向结构体变量或者数组的起始地址。
  • 语法
struct 结构体名 *指针变量列表;
  • 举例
struct Dog
{char namr[20];int age;
};struct Dog dog = {"苟富贵"5};// 基于结构体的结构体指针
struct Dog *p = &dog;
结构体成员的访问
结构体成员访问
  • 结构体数组访问结构体成员

    • 语法:

      结构体数组名 -> 成员名;
      (*结构体数组名).成员名; // 等价于上面写法
      
    • 举例:

      printf("%s:%d\n",persons->name, persons->count);
      
  • 结构体成员访问符

    • .:左侧是结构体变量,也可以叫做结构体对象访问成员符,右侧是结构体成
    • ->:左侧是结构体指针,也可以叫做结构体指针访问成员符,右侧是结构体成员
    • 举例:
    struct Persin *p = persons; // p机会结构体指针
    for(;p < persons + len; p++)printf("%s:%s\n", p->name, p->count);
    
  • 访问结构体成员有两种类型,三种方式:

    • 类型1通过结构体变量(对象|示例)访问成员

      struct Stu
      {int id;char name[20];
      }stu; // 结构体变量// 访问成员
      stu.namee;
      
    • 类型2:通过结构体指针访问成员

      • 第1种:指针访问成员

        struct Stu
        {int id;char name[20];
        }stu; // 结构体变量struct Stu *p = &stu;
        // 指针引用访问成员
        p -> name; // 等价于 (*p).name;
        
      • 第2种:指针解引用间接访问成员

        struct Stu
        {int id;char name[20];
        }stu; // 结构体变量struct Stu *p = &stu;
        // 指针引用访问成员
        (*p).name; // 等价于p -> name
        
    • 结构体数组中元素的访问

      struct Stu
      {int id;          // 编号char name[20];   // 名字(成员) float scores[3]; // 三门成绩(成员)
      }stus[3] = 
      {{1, "张三", {90,89,78}},{2, "李四", {90,88,78}},{3, "王五", {77,89,78}},
      };// 取数据 --- 下标法
      printf("%s,%.2f\n", stus[1].name, stus[1].scores[1]); // 李四 88
      // 取数据 --- 指针法
      printf("%s,%.2f\n", stus -> name, stus -> scores[2]); // 张三 78
      printf("%s,%.2f\n", (stus+1) -> name, (stus+1) -> scores[1]); // 李四 88 
      printf("%s,%.2f\n", (*(stus+1)).name, (*(stus+1)).scores[1]); // 李四 88 
      

    小贴士:

    结构体是自定义数据类型,它是数据类型,用法类似于基本类型的int;

    结构体数组它是存放结构体对象的数组,类似于int数组存放int数据;

    基本类型数组怎么用,结构体数组就怎么用 —>可以遍历,可以作为形式参数,也可以做指针等;

  • 结构体类型的使用案例

    结构体可以作为函数的返回类型、形式参数等。

    举例:

    #include <stdio.h>
    #include <string.h>/**
    * 定义一个结构体(数据类型)
    */
    struct Cat
    {char *namr;       // 姓名int age;          // 年龄char color[20];   // 颜色
    };/**
    * 结构体类型作为形式参数
    */
    void test1(struct Cat c)
    {printf("test1:\n%s,%d,%s\n", c.name, c.age, c.color);
    }/**
    * 结构体类型作为形式参数,结构体类型作为返回值类型
    */
    struct Cat test2(struct Cat c)
    {return c;
    }/**
    * 结构体数组作为形式参数
    */
    struct Cat *test3(struct Cat cats[], int len, char* name)
    {struct Cat *p = cats;for(; p < cats + len; p++){if(strcmp(name, p -> name) == 0) return p;}return NULL;
    }/**
    * 结构体指针作为形式参数
    */
    struct Cat *test4(struct Cat *cats, int len, char* name)
    {struct Cat *p = cats;for(; p < cats + len; p++){if(strcmp(name, p -> name) == 0) return p;}return NULL;
    }int main()
    {// 定义结构类型struct Cat cat = {"黑猫警长", 8, "yellow"};// 结构对象作为实际参数test1(cat);// 结构体作为函数参数和返回值struct Cat res_cat = test2(cat);printf("test2:\n%s,%d,%s\n", res_cat.name, res_cat.age, res_cat.color);// 定义一个结构体数组struct Cat cats[] = {{"汤姆", 16, "blue"},{"杰瑞", 18, "green"},{"索菲", 19, "red"}};// 结构体数组作为参数struct Cat *p1 = test3(cats,3,"汤姆");printf("test2:\n%s,%d,%s\n", p1 -> name, p1 -> age, p1 -> color);// 结构体指针作为参数struct Cat *p2 = test4(cats,3,"汤姆");printf("test2:\n%s,%d,%s\n", p2 -> name, p2 -> age, p2 -> color);return 0;
    }
    
结构体类型求大小
字节对齐
  • 字节对齐的原因:

    1. 硬件要求 某些硬件平台(如ARM、x86)要求特定类型的数据必须对齐到特定地址,否 则会引发性能下降或硬件异常。
    2. 优化性能 对齐的数据访问速度更快。例如,CPU访问对齐的int数据只需一次内存操作,而未对齐的数据可能需要多次操作。
  • 字节对齐规则:

    1. 默认对齐规则
    • 结构体的每个成员按其类型大小和编译器默认对齐数(通常是类型的自然对齐数)对齐。
    • 结构体的总大小必须是最大对齐数的整数倍。
    1. 对齐细节
    • 基本类型的对齐数char (1字节)、 short (2字节)、 int (4字节)、double(8字节)。
    • 结构体成员的对齐 :每个成员的起始地址必须是对齐数的整数倍。
    • 结构体总大小的对齐 :结构体的总大小必须是其最大对齐数的整数倍。
    1. #pragma pack(n)的影响 使用#pragma pack(n) 可以强制指定对齐数为 nn 为 1、2、4、8、16)。此时:
      • 每个成员的对齐数取 n 和其类型大小的较小值。
      • 结构体的总大小必须是n和最大对齐数中的较小值的整数倍。
  • 对齐示例

    • 默认对齐

      struct s1
      {char c;   // 1字节,偏移0int i;    // 4字节,(需对齐到4,填充3字节,偏移4-7)double d; // 8字节(需对其到8,偏移8~15)
      } // 16字节
      
      struct s2
      {double d; char c;   int i; 
      } // 16字节
      
      struct s3
      {char c; double d;   int i; 
      } // 24字节
      

      内存分析:

      在这里插入图片描述

      总结:结构体中,成员的顺序会影响到结构体最终的大小。

  • 使用#param pack(1)

    #pragma pack(1)
    struct Sl
    {char c;// 1字节(偏移0)int i;// 4字节 (偏移1~4)double d;// 8字节 (偏移5~12)
    };
    #pragma pack()
    //s1 的大小为 13字节
    
    #pragma pack(2)
    struct Sl
    {char c;// 1字节(偏移0,填充1字节) 2int i;// 4字节 (偏移2~5) 4double d;// 8字节 (偏移6~13) 8
    };
    #pragma pack()
    //s1 的大小为 14字节
    
    #pragma pack(4)
    struct Sl
    {char c;// 1字节(偏移0,填充3字节) 4int i;// 4字节 (偏移2~5) 4double d;// 8字节 (偏移6~13) 8
    };
    #pragma pack()
    //s1 的大小为 16字节
    
  • 在GNU标准中,可以在定义结构体时,指定对齐规则:

    __attribute__((packed));      -- 结构体所占内存大小是所有成员所占内存大小之和
    --attribute__((aligned(n)));  -- 设置结构体占n个字节,如果n比默认值小,n不起作用;n必须是2的次方
    
  • 案例:

    #include <stdio.h>int main(int argc,char *argv[])
    {struct cat{char sex_attribute((aligned(2)));//4 2int id;//4char name[20];//20}_attribute_((packed));//结构体所占内存大小是所有成员所占内存大小之和printf("%]d\n",sizeof(struct cat));//默认字节对齐(28)/使用packed后(25)return 0;
    }
    

柔性数组

定义:柔性数组不占结构体的大小。

语法:

struct St
{...char arr[0];
}

案例:

#include <stdio.h>
int main(int argc,char *argv[])
{struct Cat{char sex __attribute((aligned(2)));// 1 -- 2int id;           // 4char arr[0];      // 0 柔性数组不占用结构体的大小      char name[20];    // 20     } __attribute__((packed)); // 结构体所占内存大小是所有成员所占内存大小之和printf("%ld\n",sizeof(struct Cat));// 默认字节对齐(28)/ 使用packed后(25)/ 使用aligned之后(26)return 0;}

共用体/联合体类型

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

  • 定义格式

    union 共用体名称
    {数据类型 成员名;数据类型 成员名;...
    }
    
  • 共用体的定义和机构体类似。

    • 可以有名字,也可以匿名

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

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

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

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

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

  • 注意:

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

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

    • 共用体所有成员共享同一内存空间,同一时间只能存储一个值,可能导致数据覆盖

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

      • 共用体可以是共用体的成员,也可以是结构体的成员
      • 结构体可以是结构体的成员,也可以是共用体的成员
  • 案例:

    /**
    * 定义共用体
    */union S
    {cahr a;float b;int c;
    }; // S的大小是4字节// 共用体作为共用体成员
    union F
    {char a;union S s; // 4字节
    }; // F的大小是4字节// 定义一个结构体
    struct H
    {int a;char b;
    }; // H的大小是8字节// 结构体作为结构体成员
    struct I
    {int a;int b;struct H h;
    }; // I的大小是16;// 共用体作为结构体成员
    strcut J
    {int a;  // 4char b; // 1 + 3union S s; // 4
    }; // J的大小是12void test1()
    {// 定义一个共用体union Obj{int num;char sex;double score;};// 定义匿名共用体union{int a;char c;} c;// 定义变量union Obj obj;// 存储数据obj.num = 10; // 共用体空间数据:10obj.sex = 'A';// 共用体空间数据:'A' = 65// 运算obj.num += 5; // 共用体空间数据:70 覆盖数据 'F'printf("%lu,%d,%c,%.2lf\n",sizeof(obj),obj.num, obj.sex, obj.score);
    }int main()
    {text1();return 0;
    }
    

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

  • 案例:

    /**
    * 定义共用体
    */union S
    {cahr a;float b;int c;
    }; // S的大小是4字节// 共用体作为共用体成员
    union F
    {char a;union S s; // 4字节
    }; // F的大小是4字节// 定义一个结构体
    struct H
    {int a;char b;
    }; // H的大小是8字节// 结构体作为结构体成员
    struct I
    {int a;int b;struct H h;
    }; // I的大小是16;// 共用体作为结构体成员
    strcut J
    {int a;  // 4char b; // 1 + 3union S s; // 4
    }; // J的大小是12void test1()
    {// 定义一个共用体union Obj{int num;char sex;double score;};// 定义匿名共用体union{int a;char c;} c;// 定义变量union Obj obj;// 存储数据obj.num = 10; // 共用体空间数据:10obj.sex = 'A';// 共用体空间数据:'A' = 65// 运算obj.num += 5; // 共用体空间数据:70 覆盖数据 'F'printf("%lu,%d,%c,%.2lf\n",sizeof(obj),obj.num, obj.sex, obj.score);
    }int main()
    {text1();return 0;
    }
    

相关文章:

  • 【PP】SAP生产订单(创建-下达-发料-报工-入库)全流程及反向流程
  • 《P1379 八数码难题》
  • 编程日志5.28
  • w笔记--表格组件(Table)的sorter属性
  • 基于 STM32 的智慧农业温室控制系统设计与实现
  • 如何通过仿真软件优化丝杆升降机设计
  • `sysctl`命令深度剖析:如何优化内核参数以提升服务器网络/IO性能?
  • app获取相册权限是否意味着所有相片都可随时读取?
  • 力扣HOT100之回溯:131. 分割回文串
  • MySQL 只知道表名不知道具体库?如何查询?information_schema入手
  • 深入解析 Flink 中的时间与窗口机制
  • webpack CDN打包优化
  • js 实现多并发任务处理
  • 8Manage PM、Trello与飞书对比评测:哪款项目管理软件更适合企业使用?
  • DAY07:Vue Router深度解析与多页面博客系统实战
  • 数据库 1.0.2
  • Cmake编译yaml-cpp并在QT中测试成功操作步骤
  • 共现矩阵的SVD降维与低维词向量计算详解
  • 【免费】【无需登录/关注】多点矩阵计算器,计算任何坐标系转换
  • Teigha应用——解析CAD文件(DWG格式)Teigha在CAD C#二次开发中的基本应用
  • 电商网站取名/seo关键词排名优化销售
  • 网址导航主页/优化落实疫情防控新十条
  • 宿迁哪里做网站/长沙百度搜索排名
  • 跨境商城网站制作/世界杯比分查询
  • 信用门户网站建设/如何设计与制作网页
  • 一个独立IP做几个网站比较合适/最常用的搜索引擎有哪些