4

【C进阶】10、struct和union分析

 3 years ago
source link: https://segmentfault.com/a/1190000040633085
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Summary

1)空结构体的大小在不同的编译器下行为不同:gcc编译器下空结构体的大小为0;bcc和vc编译器认为空结构体的语法错误,编译错误

2)柔型数组的要点:

struct SoftArray
{
    int len;
    int array[];
};

sizeof(struct SoftArray) = 4

    struct SoftArray* sa = NULL;
    
    sa = (struct SoftArray*)malloc(sizeof(struct SoftArray) + 5*sizeof(int));

    sa->len = 5;
  • 柔性数组的最后一个数组是一个标识符不占用空间,sizeof(struct SoftArray)得到的是数组长度占用的空间。
  • 柔性数组需要从堆空间中申请,可以自由分配想要大小数组,malloc完了之后指定数组的大小。
  • 好处在于,不需要在定义的时候指定数组大小,可以在运行时指定大小带了长度信息,作为函数参数的时候不需要额外指定数组的大小。

3)union中的所有成员共享一段内存,大小为成员中最大的一个所占内存。

4)小端系统:低地址存储低位数据;大端系统:低地址存储高位数据。
使用union可以判断系统的大小端。不论大小端系统,在取uu.c的值是,都是从低地址处按字节来取

struct和union分析

1、struct

1.1 空结构体占用多大的内存?

struct TS
{
};

sizeof(struct TS) = ?

以上的代码,在不同的编译器下,结果不同:

  • gcc编译器下,空结构体的大小为0
  • bcc编译器下,编译错误
  • vc编译器下,编译错误

这对应了两种解释思路:

  • bcc、vc认为,既然结构体是存储变量的集合,如果一个结构体里什么都不放,自然是不对的,编译错误
  • gcc认为,空的结构体里什么变量都没有,自然大小为0;同时也能用空结构体类型来定义变量,大小也为0。

1.2 柔性数组

  • 柔性数组是数组大小待定的数组
  • C语言中可以由结构体产生柔性数组
  • C语言中结构体的最后一个元素可以是大小未知的数组

    struct SoftArray
    {
      int len;
      int array[];
    };
    
    sizeof(struct SoftArray) = 4

柔性数组的用法:

struct SoftArray
{
    int len;
    int array[];
};
int main()
{
    printf("sizeof(struct SoftArr) = %d\n", sizeof(struct SoftArray));

    struct SoftArray* sa = NULL;
    
    sa = (struct SoftArray*)malloc(sizeof(struct SoftArray) + 5*sizeof(int));

    sa->len = 5;

    for(int i=0; i<sa->len; ++i)
    {
        sa->array[i] = i+1;
        printf("sa->array[%d] = %d\n", i, sa->array[i]);
    }
        
    return 0;
}
  • 柔性数组的最后一个数组是一个标识符不占用空间,sizeof(struct SoftArray)得到的是数组长度占用的空间。
  • 柔性数组需要从堆空间中申请,可以自由分配想要大小数组,malloc完了之后指定数组的大小。
  • 好处在于,不需要在定义的时候指定数组大小,可以在运行时指定大小带了长度信息,作为函数参数的时候不需要额外指定数组的大小。

2、union

2.1 union占用的内存

  • C语言中的union在语法上与struc相似
  • union只分配最大成员的空间,所有成员共享这个空间。

    #pragma pack(4)
    struct Struct
    {
      int a;
      double b;
      char c;
    };
    
    union Union
    {
      int a;
      double b;
      char c;
    };
    
    int main()
    {
      printf("sizeof(struct) = %d\n", sizeof(struct Struct));   // 16
      printf("sizeof(union) = %d\n", sizeof(union Union));  // 8

2.2 系统大小端

union Union
{
    int i;
    char c;
};

int main()
{
    union Union uu;
    uu.i = 1;
    
    if(uu.c == 1)
        printf("Little ednian.");
    else
        printf("Big ednian.");

    return 0;
}

如果是小端系统,低地址存储低位数据,这段内存中“1”就会放在低地址处,这样取c的值(1字节)就是1;
如果是大端系统,低地址存储高位数据,这段内存中“1”就会放在高地址处,这样取c的值(1字节)就是0。

本文总结自“狄泰软件学院”唐佐林老师《C语言进阶课程》。
如有错漏之处,恳请指正。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK