定义

  1. struct 结构体类型名称 {
  2. 属性;
  3. }
// 1.定义结构体类型
struct Person
{
//        char name[20];
    char *name;
    int age;
    double height;
}
// 2.定义结构体变量
struct Person p;
// 注意: 数组不能先定义再进行一次性的初始化, 所有下面的写法是错误的
//    p.name = "lnj"; // name = {'l', 'n', 'j', '\0'};
// 可以使用 结构体变量名称.属性的方式给结构体变量赋值
p.name = "jkl";
p.age = 30;
p.height = 1.75;

初始化方式

// 1.定义的同时初始化
struct Person sd = {"jkl", 13, 5.0};

// 2.先定义再初始化(逐个初始化)
struct Person p;
p.name = "jkl";
p.age = 30;
p.height = 1.75;

// 3.先定义再初始化(一次性初始化)
struct Person sd2;
// 特别注意: 结构体和数组有一点区别, 数组不能先定义再进行一次性的初始化, 而结构体可以
// 只不过需要明确的告诉系统{}中是一个结构体
sd2 = (struct Dog){"xq", 8, 8.8}; // 数组? 结构体?  加上类型转换,指定为 结构体

// 4.指定将数据赋值给指定的属性
struct Person sd3 = {.height = 1.77, .name = "ww", .age = 33};

结构体的存储方式

  • 定义结构体类型并不会分配存储空间
  • 只有定义结构体变量才会真正分配存储空间
  • 结构体地址 == 结构体 第0个元素 的地址
  • 先存储第0个属性,在依次存储其他属性(跟数组一样) ```c // 1.定义结构体类型并不会分配存储空间 struct Person{ int age; // 4 int height; // 4 int width; // 4 }; // 2.只有定义结构体变量才会真正的分配存储空间 struct Person sp = {30, 1, 1}; // 结构体第0个属性的地址就是结构体的地址 printf(“&sp = %p\n”, &sp);//0x7ffeefbfeef0 printf(“age = %p\n”, &sp.age);//0x7ffeefbfeef0

printf(“size = %lu\n”, sizeof(sp));//12

// 先存储第0个属性, 再依次存储其它属性 printf(“height = %p\n”, &sp.height);//0x7ffeefbfeef4 printf(“width = %p\n”, &sp.width);//0x7ffeefbfeef8


**结构体如何开辟存储空间?**<br />**

- 将所有属性占用的存储空间的总和加在一起后再分配,这种说法不完全正确
- 注意
   - 结构体分配存储空间本质上并不是将所有属性占用的存储空间的总和加在一起后再分配;
   - 是获取结构体类型中占用内存最大的属性的大小, 然后取该大小的倍数
- 特例
   - 如果剩余的存储空间"不够"存储将要存储的数据, 那么就会重新开辟8个字节的存储空间, 并且将需要存储的数据放到新开辟的存储空间中
   - 如果剩余的存储空间"够"存储将要存储的数据, 那么就不会开辟了

<a name="5Etm6"></a>
### 指向结构体的指针
```c
struct Person *p = &sp;
(*p).age = 40;//(*p)必须带上括号,因为 . 运算符的优先级  高于 *
p->height = 2;