C语言结构体


结构体

??1、结构体的概念:由多个相同或不同的数据类型组成的集合,集合内有多个用来描述的属性。

??2、结构体的声名:
????typedef struct student{
???????成员属性列表;
????}student_t;

????声明的结构体类型是一个新的数据类型。

??3、定义结构体类型的变量:
????student_t?stu;?--------》?定义一个结构体类型的变量
????student_t?stu1;?--------》?定义一个结构体类型的指针
????student_t?stu2[2];?--------》定义一个结构体类型的数组
????student_t?
stu3[2];?--------》定义一个结构体类型的指针数组
????student_t?(*stu4)[2];?--------》定义一个结构体类型的数组指针

??4、对结构体变量的初始化:
????(1)、定义的同时进行初始化
????????student_t?stu?=?{value1,value2,......................};

????(2)、先定义,后初始化
????????student_t?stu;
????????student_t? *stu1 = &stu;

????(3)、已经初始化的结构体,对另一个相同类型的结构体进行初始化(要求两个结构体类型一致)
????????student_t?stu;
????????student_t? *stu1 = &stu;
????????student_t?stu5 = stu;
??5、结构体中成员的访问:
????普通的结构体类型变量使用 "."
??????格式:
????????结构体变量名?.?成员名;

??????结构体指针类型变量使用 "->"
??????格式:
????????结构体变量指针?->?成员名;
??6、在一个结构体之中是不能在定义一个与自身结构体类型相同的变量,但是可以定义一个与自身结构体类型相同的结构体类型指针。
????例如:
??????typedef?struct?A1{
????????int?i;
????????int? *j;
????????struct?A1? *L;
????????//struct A1 H; //结构体里是无法定义一个与它自身结构体同类型的变量的。
??????}A1_t;

???????为什么?
?????????因为我们在定义好结构体的成员变量之后,系统会计算这个结构体占用的内存的大小。
?????????但是 H 是一个 struct A1 类型的变量,所以只有在定义好之后才能计算这个结构体占用的内存的大小,
?????????那么我们在定义H时,它的大小又是多少呢? 我们是不知道的。
?????????所以无法在一个结构体中定义一个与结构体类型相同的变量。
?????????因为无论什么类型的指针都占4个字节,所以我们是可以在结构体内,定义一个与结构体同类型的指针。

结构体的内存的对齐的问题

????结构体对齐原则:在结构体内,有大于int类型(或有int类型)的数据时,按4字节进行对齐。
????????????如果在结构体内,没有大于int类型的数据时,按最大的那个类型进行对齐

????#include
????size_t offsetof(type , member);
????功能:计算结构体中指定成员,相对于结构体开始地址偏移的字节个数;
????参数:
??????@type:结构体
??????@member:结构体成员的地址
????返回值:
??????成功:返回偏移的字节个数。
?????
?????
?????可以看到字符b占用了两个字节,那是为什么呢?这就是结构体对齐的问题;

点击查看代码
   数据类型:
        char    1个字节
        short   2个字节
        int 和 float   4个字节
        double  8个字节
        指针类型     4个字节

    参考案例:08struct.c
        #include 
        struct aa{
            char a;
            char b;
            char c;
        };
        struct bb{
            char a;  // 1
            char b;  // 1
            char c;  // 1
            // 保留一个字节
            short d; // 2
        };
        struct cc{
            char a;  // 1
            char b;  // 1
            char c;  // 1
            // 保留一个字节
            short d; // 2
            // 保留2个字节
            int  e;   // 4
        };
        struct dd{
            char a;  // 1
            char b;  // 1
            char c;  // 1
            // 保留一个字节
            short d; // 2
            // 保留2个字节
            int e;   // 4
            double f;  // 8
        };