【基础知识】结构体(struct)和联合体(union)

这篇具有很好参考价值的文章主要介绍了【基础知识】结构体(struct)和联合体(union)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1. 结构体(Struct)

1.1 C++ 结构体和 C 语言结构体的区别

1.2 结构体的对齐方式

2. 联合体(Union)

2.1 联合体特性

3. 结构体和联合体的区别


1. 结构体(Struct)

        在 C 语言中,结构体是一种自定义的复合数据类型,允许将不同数据类型的变量组合成一个单一的实体。结构体可以包含多个成员,每个成员可以是不同的数据类型,如整数、浮点数、字符、数组等。

        结构体的定义通常在函数外部,并且在函数内部可以声明和使用结构体类型的变量。结构体的定义包含了结构体的名称和结构体成员的列表,每个成员都有一个名称和一个数据类型。结构体的成员可以通过成员运算符(.)来访问。

以下是一个简单的 C语言 结构体的示例:

#include <stdio.h>

// 定义一个名为Student的结构体
struct Student {
    int roll_no; // 学号
    char name[50]; // 姓名
    int age; // 年龄
    float score; // 分数
};

int main() {
    // 声明并初始化一个Student类型的结构体变量
    struct Student student1 = {101, "Alice", 20, 95.5};

    // 访问结构体成员并输出
    printf("Roll No: %d\n", student1.roll_no);
    printf("Name: %s\n", student1.name);
    printf("Age: %d\n", student1.age);
    printf("Score: %.2f\n", student1.score);

    return 0;
}

1.1 C++ 结构体和 C 语言结构体的区别

        C++ 中的结构体和 C 语言中的结构体在语法上基本上是一致的,但在 C++ 中,结构体还具有类的特性,包括封装、继承和多态等,从而与 C 语言中的结构体有一些区别。

主要区别如下:

  • 成员函数:C 的结构体内不允许有函数存在,C++ 中的结构体可以包含成员函数,且允许该函数是虚函数,这是与 C 语言中的结构体最大的不同之一。C++ 中的结构体可以像类一样定义成员函数,可以在结构体内部绑定成员函数的实现,并在结构体对象上调用这些成员函数。
  • 访问控制:C++ 中的结构体可以使用 public、protected、private 关键字来限制成员变量的访问权限,从而实现封装性;而 C 语言中的结构体对内部成员变量的访问权限只能是 public,可以在任何地方被访问。
  • 继承:C++ 中的结构体可以通过继承从其他结构体或派生类,从而实现继承的特性,包括单继承和多继承;而 C 语言中的结构体没有继承的概念。
  • 构造函数和析构函数:C++ 中的结构体可以定义构造函数和析构函数,用于对象的初始化和清理操作;C 语言中的结构体没有构造函数和析构函数的概念。
  • 默认访问修饰符:C++ 中的结构体成员默认是 private 访问修饰符,而 C 语言中的结构体成员默认是 public 访问修饰符。
  • C 中使用结构体需要加上 struct 关键字,或者对结构体使用 typedef 取别名,而 C++ 中可以省略 struct 关键字直接使用.

1.2 结构体的对齐方式

        结构体对齐根据最大类型长度对齐。结构体大小一定是最大成员的整数倍

对齐规则:

  • 结构体变量的首地址能够被其最宽基本类型成员的大小所整除

        编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该基本数据类型所整除的位置,作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐摸数。

  • 结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍

        如有需要编译器在成员之间加上填充字节作为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员大小的整数倍,若是,则存放本成员,反之,则在成员和上一个成员之间填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。

  • 结构体的总大小为结构体最宽基本类型成员大小的整数倍

        如有需要编译器会在最末一个成员之后加上填充字节,结构体总大小是包括填充字节,最后一个成员满足上面两条以外,还必须满足第三条,否则就必须在最后填充几个字节以达到本条要求。

例如:

//1.
struct A
{
    char c1;    //大小 (char)1 + 3(填充数)
    int i;      //大小 (int)4
    char c2;    //大小 (char)1 + 3(填充数)
}
//该结构体对齐数为 4(int),则结构体大小为 
//(1 + 3)+ 4 +(1+3)=12




//2.
struct A
{
    char c1;    //大小 (char)1 + 3(填充数)
    int i;      //大小 (int)4
    char c2;    //大小 (char)1
    char c3[5];  大小 (char)1 * 5 + 2(填充数),
    //因为是以4对齐,c2为1个字节,还剩3个位置给c3,
    //然后c3的最后两个字节位置再开辟下一行,新一行没有满足4,则再加2个填充数。
}
//该结构体对齐数为 4(int),加上一个char类型的数组
//可以看作有5个char类型存入内存中,则结构体大小为:
//(1+3)+ 4 + 1 + 5 + 2 =16





//3.
struct A
{
    char c1;//1+3
    int i;//4
    char c2;//1+7
    double c[5];//40
};
//该结构体对齐数为 8(double),加上一个double类型的数组
//可以看作有5个double类型存入内存中,则结构体大小为:
//(1+3)+ 4 + 1 + 7 + (8*5) =56



2. 联合体(Union)

        在 C 语言中,联合体是一种特殊的数据结构,可以在内存中共享同一段存储空间来存储不同类型的数据。与结构体类似,联合体也是一种用户自定义的数据类型,可以包含多个不同类型的成员变量。

        联合体的定义使用关键字‘union’,后面紧跟联合体的名称和一对花括号,括号中定义了联合体的成员变量,每个成员变量有自己的名称和数据类型。

#include <stdio.h>

// 定义一个联合体
union Data {
    int i;
    float f;
    char c;
};

int main() {
    union Data data; // 声明一个联合体变量data

    data.i = 42; // 给联合体的整数成员赋值
    printf("data.i = %d\n", data.i); // 输出整数成员的值

    data.f = 3.14; // 给联合体的浮点数成员赋值
    printf("data.f = %.2f\n", data.f); // 输出浮点数成员的值

    data.c = 'A'; // 给联合体的字符成员赋值
    printf("data.c = %c\n", data.c); // 输出字符成员的值

    // 注意:联合体的不同成员共享同一块内存空间,赋值一个成员会影响其他成员的值
    printf("data.i = %d, data.f = %.2f, data.c = %c\n", data.i,data.f, data.c);
    //data.i = 1078523201, data.f = 3.14, data.c = A

    return 0;
}

2.1 联合体特性

  • 联合体是一个结构
  • 它的所有成员相对于基地址的偏移量都为 0
  • 次结构空间要大到足够容纳最“”的成员;
  • 其对齐方式要适合其中所有的成员;

3. 结构体和联合体的区别

        (1)结构体中的每个成员都占用独立的内存空间,而联合体中的所有成员共享同一块内存空间。这意味着,在联合体中只有一个成员变量能够同时存储值,而其他成员变量会被覆盖;

        (2)结构体的内存占用大小等于所有成员的内存大小之和,而联合体的内存占用大小等于其最大成员的内存大小,因此,联合体在内存占用上通常比结构体更节省;

        (3)结构体的成员可以同时被访问和修改,而联合体的成员只能同时访问和修改一个成员。这是因为联合体的成员共享同一块内存空间,修改其中一个成员会影响其他成员的值。

        (4)结构体的成员在内存中按照定义的顺序依次排列,而联合体的所有成员共享同一块内存空间,因此只有一个成员可以存储有效值;

        (5)结构体的初始化可以为每个成员分别赋值,而联合体的初始化只能对其中一个成员赋值。

 文章来源地址https://www.toymoban.com/news/detail-728335.html

到了这里,关于【基础知识】结构体(struct)和联合体(union)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C/C++之自定义类型(结构体,位段,联合体,枚举)详解

    专栏分类:C语言初阶      C语言程序设计————KTV       C语言小游戏     C语言进阶 C语言刷题 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂。 目录 个人主页:点我进入主页   1.前言 2.结构体 2.1结构体声明 2.2结构体初始化 2.3结构体的自引用 2,4结构体的内存

    2024年02月08日
    浏览(40)
  • C语言中的结构体和联合体有什么区别?

    结构体 是一种用户自定义的数据类型,用于组合不同数据类型的变量,使它们可以作为一个单元一起使用

    2024年02月08日
    浏览(51)
  • C语言中的“三体”大佬们知道是什么吗? —— 结构体、枚举、联合体

    目录 前言 结构体 基本概念 结构体类型的声明 结构的声明 特殊的声明 结构的自引用 结构体变量的定义和初始化 结构体的对齐规则: 为什么要内存对齐 修改默认对齐数 修改默认对齐数的预处理命令 实际例子 结构体传参 结构体实现位段(位段的填充) 位段 什么是位段 位

    2024年02月12日
    浏览(66)
  • C语言学习(三十一)---结构体、联合体的在内存中的存储

    在上一篇文章中,我们学习了 枚举 、 位段 和 联合体 的相关内容,在文章的末尾,我们还差了关于 联合体的存储 问题的内容,今天我们将学习该部分的内容,好了,话不多说,开整!!! 结构体 在内存中是如何存储的呢,是按里面的变量内容,在 内存中的连续地址中存

    2024年02月12日
    浏览(41)
  • 【C语言】一篇文章深入解析联合体和枚举且和结构体的区别

    联合体( union )是允许一个变量通过不同的接口访问内存的一种数据类型,表示一个变量可以存储不同类型的值,而枚举是使用 enum 定义一组相关且互斥的整形常量集合。本章阿森将和你学习联合体类型的声明,特点,有关大小的计算,还有枚举类型的声明,优点和使

    2024年02月03日
    浏览(52)
  • 一篇博客学会系列(2)—— C语言中的自定义类型 :结构体、位段、枚举、联合体

    目录  前言 1、结构体 1.1、结构体类型的声明 1.2、特殊的结构体类型声明 1.3、结构体的自引用 1.4、结构体的定义和初始化 1.5、结构体成员变量的调用 1.6、结构体内存对齐  1.6.1、offsetof 1.6.2、结构体大小的计算 1.6.3、为什么存在内存对齐?  1.7、 修改默认对齐数 1.8、结构

    2024年02月08日
    浏览(42)
  • 联合体(C语言)

    小伙伴们又来学习知识啦~,今天我要给大家介绍一下联合体的使用,话不多说,我们开始今天的正题吧! 联合体的介绍 C语言的联合体(union)是一种特殊的数据类型,它可以在同一内存空间中存储不同的数据类型。与结构体类似,联合体也可以定义多个成员,但是这些成员

    2024年02月04日
    浏览(48)
  • 十五、联合体(union)

    十五、联合体(union) 1、union语法 ​ 联合体和结构体都是自定义数据类型 ,通过union可以创建一个联合体,union中的成员变量 共享内存 (即内存中有重叠的部分),因此union的数据类型大小由其最大的成员变量决定。 2、union的特点及使用 ①union中任意一个成员变量的变动,

    2024年02月05日
    浏览(50)
  • 联合体union

    结构体中的成员彼此是独立存在的,分布在不同的内存单元中 共用体的成员是“一体的”,使用同一个内存单元 小端:高位地址在高位,低位地址在低位 大端:高位地址在低位,低位地址在高位     

    2024年02月13日
    浏览(39)
  • 自定义类型——枚举与联合体

    枚举顾名思义就是一一列举 把可能的取值一一列举 以上定义的 enum Day , enum Sex 都是枚举类型  { }中的内容是枚举类型的可能取值,也叫 枚举常量 这些可能取值都是有值的,默认从0开始,一次递增1 当然在定义的时候也可以赋初值 例如: 我们可以使用 #define 定义常量,为

    2023年04月19日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包