`

结构体struct && 联合union

    博客分类:
  • C
阅读更多
1.C语言中的结构体

1.1 定义

结构体是由一系列相同或不同类型的变量组成的集合。

struct 结构体名{               //struct为关键字,“结构体名”为用户定义的类型标识。

数据类型1 成员名1;          //{ }中是组成该结构体的成员,其中数据类型可以是C语言所允许的任何数据类型。

数据类型2 成员名2;

...

数据类型n 成员名n;

};

1.2 结构体的内存分配(方法一)

结构体在内存中分配一块连续的内存,但结构体内的变量并不一定是连续存放的,这涉及到内存对齐。

原则1  数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。

原则2  结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)

原则3  收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。

例1.



struct A{                            struct B{
      int a;                                char b;
      char b;                               int a;
      short c;                              short c;
         };                                   };

sizeof(A) = 8; int为4,char为1,short为2,这里用到了原则1和原则3。
sizeof(B) = 12; char为1,int为4,short为2,怎么会是12?还是原则1和原则3。

           a         b         c
A的内存布局:1111,     1*,       11

           b          a        c
B的内存布局:1***,     1111,   11**


其中星号*表示填充的字节。

A中,b后面为何要补充一个字节?因为c为short,其起始位置要为2的倍数,就是原则1。c的后面没有补充,因为b和c正好占用4个字节,整个A占用空间为4的倍数,也就是最大成员int类型的倍数,所以不用补充。

B中,b是char为1,b后面补充了3个字节,因为a是int为4,根据原则1,起始位置要为4的倍数,所以b后面要补充3个字节。c后面补充两个字节,根据原则3,整个B占用空间要为4的倍数,c后面不补充,整个B的空间为10,不符,所以要补充2个字节。

例2.



struct A{                               struct B{
    int a;                                  char e[2];
    double b;                               int f;
    float c;                                double g;
        };                                  short h;
                                            struct A i;
                                                  };

sizeof(A) = 24; int为4,double为8,float为4,总长为8的倍数,补齐,所以整个A为24。

sizeof(B) = 48; 看看B的内存布局。

            e         f       g              h          
B的内存布局:11* *,   1111,   11111111, 11 * * * * * *,       

            i
           1111* * * *, 11111111, 1111 * * * *

  


  i其实就是A的内存布局。根据原则2,i的起始位置要为8的倍数,所以h后面要补齐。

1.3 结构体的内存分配(方法二)

struct的内存大小为每个数据内存的加和,首先按照最大的数据类型进行单个分配,如果前一个数据占用不了所有的内存,而剩下的内存可以放下下一个数据,则第二个数据不另外分配内存(但是地址必须是从这个数据类型大小的整数倍开始,看下面的struct C),否则重新分配一个最大类型的内存。(个人觉得这种方法比较好理解!)

例3.

struct A{                            struct B{                           struct C{
     int a;                             int a;                               int a;
    char b;                            double b;                             char b;
    double c;                          char c;                               short c;
         };                                   };                            char d;
                                                                                }
对于结构体A:
因为A中最大的数据类型是double,占8个字节。所以系统先分配8个字节用来放int,结果int只需要4个就够了,然后剩下的4个字节中的1个可以用来放后面的char,碰到double c时,因为此时的3个字节不能存下,所以再分配了一个8个字节来存放double c。因此A占用16个字节。

对于结构体B:

系统碰到int分给他8个字节存放,碰到double时,剩下的4个字节不足以存放,所以再分配了8个字节,再遇到char时又分配了8个字节,这样B共分配了24个字节。(系统其实是浪费了5个字节的空间)

比较A和B,只有变量定义的顺序不一样,结果占用的内存空间也不一样。所以,结构体里面最好按照类型从小到大的顺序来排列,以免浪费空间。

对于结构体C:

按照上述方法,最大的数据类型是int,占4个字节,系统先分配4个字节(0~3);再分配4个字节(4~7),存放char b;short c占2个字节,但是必须从2的整数倍开始,所以应当分配(6~7),中间空余1个字节;char d占1个字节,但是上次分配的4字节用完了,所以需要再分配4个字节存放char d,d只占用1个字节,所以剩下3个字节空闲。sizeof(struct C)=12。

2. C++中的结构体与类的区别

C中的结构体不允许有函数,而C++中的结构体允许。

类与结构体在C++中只有两点区别,除此这外无任何区别。

1)class中默认的成员访问权限是private的,而struct中则是public的。   

2)从class继承默认是private继承,而从struct继承默认是public继承。

3. 联合union

3.1 定义

联合(又叫共用体)是一种特殊形式的变量,使用关键字union来定义 ,它的声明与变量定义与结构体十分相似。其形式为:   

union 联合名

{    

数据类型 成员名;    

数据类型 成员名;    

...   

} 变量名;

联合表示几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。在union中,所有的联合成员共用一个空间,并且同一时间只能储存其中一个成员变量的值。

3.2 联合的内存分配

Union的大小为其内部所有变量的最大值,并且按照类型最大值的整数倍进行内存对齐。

union A            union B             union C                  union D
{                  {                   {                        {
char c[10];        char c[10];         char c[10];              char c;
char cc1;          int  i;             double d;                int i;
}u1;               }u2;                }u3;                     double d;
                                                                 }u4;
union A :首先按照char c[10]分配10个字节,然后按照char的1个字节对齐,最终sizeof(u1)=10;
union B :首先按照char c[10]分配10个字节,然后按照int的4个字节对齐,最终sizeof(u2)=12; (大于等于10且能被4整除的最小的数,即12)

union C :首先按照char c[10]分配10个字节,然后按照doube的8个字节对齐,最终sizeof(u3)=16;(大于等于10且能被8整除的最小的数,即16)

union D:按照double分配8个字节,最终sizeof(u4)=8;

3.3 应用

在C/C++程序的编写中,当多个基本数据类型或复合数据结构要占用同一片内存时,我们要使用联合体;当多种类型,多个对象,多个事物只取其一时(我们姑且通俗地称其为“n 选1”),我们也可以使用联合体来发挥其长处。



union myun
{
struct { int x; int y; int z; }u;
int k;
}a;
int main()
{
a.u.x =4;
a.u.y =5;
a.u.z =6;
a.k = 0;
printf("%d %d %d\n",a.u.x,a.u.y,a.u.z);
return 0;
}


union类型是共享内存的,以size最大的结构作为自己的大小,这样的话,myun这个结构就包含u这个结构体,而大小也等于u这个结构体的大小,在内存中的排列为声明的顺序x,y,z从低到高,然后赋值的时候,在内存中,就是x的位置放置4,y的位置放置5,z的位置放置6,现在对k赋值,对k的赋值因为是union,要共享内存,所以从union的首地址开始放置,首地址开始的位置其实是x的位置,这样原来内存中x的位置就被k所赋的值代替了,就变为0了,这个时候要进行打印,就直接看内存里就行了,x的位置也就是k的位置是0,而y,z的位置的值没有改变,所以应该是0,5,6。

4.结构体和联合的区别:

1)联合和结构体都是由多个不同的数据类型成员组成,但在任何同一时刻,联合只存放了一个被选中的成员,而结构体的所有成员都存在。   

2)对于联合的不同成员赋值,将会对其它成员重写,原来成员的值就不存在了,而对于结构体的不同成员赋值是互不影响的。
分享到:
评论

相关推荐

    struct和union结构体和联合体的区别.pdf

    ### Struct和Union结构体和联合体的区别 #### 一、基本概念 - **Struct(结构体)**:在C语言中,`struct`是一种用户自定义的数据类型,它允许将不同类型的变量组合在一起,形成一个新的复合数据类型。结构体中的...

    systemverilog中struct和union的一种用法

    SystemVerilog 中 struct 和 union 的应用 SystemVerilog 是一款功能强大的硬件描述语言,广泛应用于 FPGA 和 ASIC 设计中。其中,struct 和 union 是两种常用的数据结构,它们可以用来组织和存储数据。本文将介绍 ...

    file结构体和inode结构体

    ### 文件结构体 (`struct file`) 与 索引节点结构体 (`struct inode`) #### 一、`struct file` 结构体 `struct file` 是 Linux 内核中的一个重要数据结构,它用来描述内核空间中每一个打开的文件。这个结构体在 `...

    C语言程序设计课件:8 结构体&共用体.ppt

    在C语言中,结构体(struct)是一种复合数据类型,它允许我们将不同类型的数据组合到一个单一的结构中,便于管理和操作。在“C语言程序设计课件:8 结构体&共用体.ppt”中,主要讲解了如何使用结构体来处理类似学生...

    union和struct混合使用C++源码

    本程序中定义了一个结构体,其成员有一个union,union中又定义了一个结构体,很好的体现了使用union的方法

    深入了解C++ 结构体(struct)与共用体(union)

    结构体(struct)与共用体(union)是C语言中就已经存在的数据类型,C++对他们进行了扩充,最大的变化是允许在结构和公用体中定义成员函数。下面将通过实例讲解二者的特性和用法。 1.struct 以下是一个使用了结构体...

    结构体使用详解,与结构体如何嵌套使用

    联合(union)与结构体类似,但是它所有的成员共享同一段内存空间。当一个结构体中包含联合时,可以通过多种方式访问联合中的成员变量。 ##### (1) 联合成员变量的直接访问 如果联合中的成员是基本数据类型,则...

    C语言中struct和union有啥区别

    ### C语言中struct和union的区别 #### 一、概述 在C语言中,`struct` 和 `union` 都是用来创建复杂数据类型的构造数据类型。它们允许开发者将多个不同类型的变量组合在一起,以便更高效地管理和操作数据。尽管两者...

    CODESYS之结构体的使用.doc

    在编程领域,结构体(Struct)是一种非常重要的数据类型,它允许我们将多个不同类型的变量组合成一个单一的实体,方便管理和操作。在CODESYS这种基于IEC 61131-3标准的编程环境中,结构体的使用是提高代码组织性和...

    ch10-C-struct-union.rar_struct and union_union

    在提供的压缩包文件 "ch10-C-struct-union" 中,很可能包含了一些示例代码,演示了如何定义、初始化和操作结构体和联合体,以及如何访问和输出它们的成员。这些实例可以帮助你更好地理解这两个概念,并通过实践加深...

    结构体和共用体sruct union typedef

    #### 一、结构体(Struct) **定义与概念:** 结构体是一种用户自定义的数据类型,它允许我们创建包含不同数据类型的复杂数据结构。结构体的主要用途是将一组相关的数据组合在一起,形成一个整体。 **基本格式:**...

    C语言 结构体范例代码

    ### 结构体联合(union) 虽然这不是标题所提及的,但值得一提的是,C语言还提供了`union`,它允许在一个内存位置存储不同类型的数据。与结构体不同,联合中的所有成员共享同一块内存,因此它的大小等于其最大成员的...

    C语言结构体讲解课件

    **结构体(struct)** 是C语言中的一种复合数据类型,它可以包含不同数据类型的成员。通过结构体,开发者能够更灵活地组织和管理数据。 #### 二、结构体类型定义 结构体类型定义的基本格式如下: ```c struct ...

    Struct、union、enum

    ### 结构体、联合、枚举在C语言中的应用 #### 一、结构体类型概述 **结构体**是C语言中的一种复杂数据类型,它允许开发者将不同类型的数据组织在一起作为一个整体来处理。通过结构体,可以有效地表示现实世界中的...

    结构体通信

    在进行网络通信时,特别是在使用低级别的套接字(socket)接口时,数据传输往往涉及到结构体(struct)的序列化和反序列化。这里的问题是,在接收端如何区分通过`recv`函数接收到的不同类型的结构体。这个问题的核心...

    C语言结构体共2页.pdf.zip

    在C语言中,结构体(struct)是一种复合数据类型,它允许我们将多个不同类型的变量组合成一个单一的实体。这使得我们能够以更有序、更符合逻辑的方式组织数据,尤其在处理复杂的数据结构时非常有用。"C语言结构体共2...

    第十一章 结构体和.ppt

    struct 结构体名 { 类型说明符 成员名; // ... }; ``` 例如,定义一个名为`student`的结构体: ```c struct student { int num; char name[20]; char sex; float score; }; ``` 11.1.1 结构体类型的概念 ...

    Delphi 嵌套结构体流化,复制,释放

    结构体流化,复制,释放(含嵌套结构体指针,普通指针,动态数组(string,指针,结构体含指针),string,anstring等情况)(基本解决内存泄漏,非法内存访问问题). 上一个资源没完成动态数组,这个完成了,并跟踪了...

Global site tag (gtag.js) - Google Analytics