关于c:C进阶10struct和union分析

38次阅读

共计 1900 个字符,预计需要花费 5 分钟才能阅读完成。

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 语言进阶课程》。
如有错漏之处,恳请斧正。

正文完
 0