结构体、联合体、枚举

结构体:

struct Student

{

  char name[32];

  int age;

  int sex;

  char add[32];

};

上面只是一种数据类型(同int、char基本类型一样),表示是一个结构体,不占用地址空间,只有在定义结构体变量时才分配空间,即struct Student stu1;stu1才占有地址空间。

结构体大小的计算:

  规则:

  1. 结构体成员变量的偏移量为该成员变量大小的整数倍。(第一个成员变量的偏移量为0,0是任何数的整数倍;结构体成员变量的偏移量不是数组和内套结构体整数倍

  2. 结构体的大小必须是所有成员变量大小的整数倍(数组和内套结构体除外)

struct Test1{       //   当前偏移量        成员变量大小          所占大小  
    char a;         //    0          1             1 
    char b;         //   1          1              2 
    char c;         //   2         1             3
    int tmp;       //    3         4          8 //当前偏移量3不是该成员变量大小(4)的整数倍,所以3要加1变成4。最后所占的空间为8,满足是所有成员变量大小的整数倍
};
sizeof(struct Test1) = 8

struct Test2{
    char a;            // 0 1 1
    int  tmp;          //   1 4 8//当前偏移量1不是该成员变量大小(4)的整数倍,所以1要加3变成4,所这时占的空间大小为8
    char b;            // 8 1 9//9不是所有成员变量大小的整数倍,所以还要加3,即12是4或1的整数倍
};
sizeof(struct Test2) = 12

struct Test3{
    char   a;          //   0       1 1
    int  tmp;          //   1           4 8//当前偏移量1不是该成员变量大小(4)的整数倍,所以1要加3变成4,这时所占的空间大小为8 
    char str[8];       //   8           8 16 //这里可以不是数组的整数倍,但必须是另外两个成员变量的整数倍
};
sizeof(struct Test3) = 16

struct Test3_1{
    char   a;          //   0       1 1
    int  tmp;          //   1           4 8//当前偏移量1不是该成员变量大小(4)的整数倍,所以1要加3变成4,这时所占的空间大小为8 
    char str[9];       //   8           9 17 //这里偏移量不为该成员变量大小的整数倍。所以所占空间的大小为17。17不是4的整数倍,所以17要加3,即20是4或1的整数倍
};
sizeof(struct Test3_1) = 20;

//对于有内嵌结构体的结构体,要先计算内嵌结构体的大小,然后再加上外部变量
struct Test4{
    char   a;          //  0 1   1
    int  tmp;          //  1  4 8 

    struct B{   // 8 8 8 16
        char c; // 1
        int  b; // 4+3   
    }b1;//这里要定义一个b1变量,没有b1的话,就不对了
    float e;           // 16 4 20//20可以不为内嵌结构体大小的整数倍,但必须是其他成员变量的整数倍
};
sizeof(struct Test4) = 20;

struct Test4_1{
    char   a;          //  0 1   1
    int  tmp;          //  1  4 8 

    struct B{   // 12 8 12 20//这里的偏移量不为该成员变量的整数倍,所以所占空间大小为20
       int  b; // 4 
    char c; // 5
       int d; // 12      
    }b1;//这里要定义一个b1变量,没有b1的话,就不对了
    float e;           // 20 4 24//24可以不为内嵌结构体大小的整数倍,但必须是其他成员变量的整数倍
};
sizeof(struct Test4_1) = 24;

struct Test4_2{
    char   a;          //  0 1   1
    int  tmp;          //  1  4 8 

    struct B{   // 16 8 16 24//这里的偏移量不为该成员变量的整数倍,所以所占空间大小为20
    char c; // 1
       double d; // 16      
    }b1;//这里要定义一个b1变量,没有b1的话,就不对了
    float e;           // 24 4 28//28可以不为内嵌结构体大小的整数倍,但必须是内嵌结构体中成员变量(double)的整数倍和外部成员变量的整数倍。
//所以也要为double的整数倍
};

//对齐值小于最大类型成员值

#pragma pack(4)  //指定向4对齐 最大是8

struct Test5{

char ch; //1

int i;//8

float f;//12

double d;//12      8      20  //偏移值12是4的整数倍,不用是8的整数倍

};

sizeof(struct Test5) = 20//如果我们没有指定对齐值,这个结构体大小是24,我们指定向4对齐,所以大小是4的倍数,所以结构体大小是20。

 

//对齐值大于最大类型成员值

#pragma pack(10)

struct Test6{
  char ch; //1

  int i;  //8

  float f;// 12

  double d;//12       8      24//12不是8的整数倍,所以要加4,即为16

};

sizeof(struct Test6) = 24//我们指定的对齐值是10,最大为8,是否就向10对齐?不是,当指定对齐值大于自身对齐值时,向自身对其值对齐,大小是24.

 

 

 

联合体(共用体):有时同一地址空间存放类型不同,不同类型的变量共享一块空间

  结构体的元素有自己单独的空间,而共用体元素共享空间,空间的大小由最大的类型确定

  结构体元素互不影响,共用体赋值会导致覆盖,

union Test

{

  int idata;

  char cdata;

  double ddata; //8字节

}

union Test u1;

u1.idata = 10;

u1.cdata = 20;

printf("idata = %d\n", u1.idata); // 这里的值为20,它把前面的值覆盖了

 

枚举:

枚举也是一种数据类型,也要定义

enum Weekend {sun,mon,tus,wed,thu,fri,sat};

posted @ 2023-04-02 23:05  踏浪而来的人  阅读(35)  评论(0编辑  收藏  举报