1、简单地声明一个结构体和定义结构体变量

文章目录三. 结构体变量的初始化四. 结构体成员的访问方法五. 结构体大小的计算 六. 柔性数组 七. C++ 中与 class 的区别八. C 和 C++ 结构体的区别
一. 结构体简述
具有相同或不同类型元素的集合叫做结构体 。定义一个结构体 , 本质是在制作一个类型:
// 声明一个学生信息结构体struct Student{char name[20];int age;};int main(){// 定义出两个学生变量struct Student s1 = { "张三", 18};struct Student s2 = { "李四", 20};return 0;}
二. 结构体的声明和定义 1、简单地声明一个结构体和定义结构体变量
在C中 , 结构体内只能存放各种类型的变量 , 不能存函数:
像上面这样就是声明了一个结构体  , 此时的相当于一个类型名 。
然后我们可以用这个自己声明的结构体类型去定义变量:
补充:C 和 C++ 中定义结构体变量的区别
2、声明结构体的同时也定义结构体变量
也许初期看不习惯容易困惑 , 其实这就相当于两步合并一步:先定义结构体 , 再定义变量 s1 和 s2:
3、匿名结构体
使用方式:声明结构体的时候缺失结构体名 , 同时定义出一个或n个结构体变量:
这种形式只能使用在声明结构体的同时也定义出结构体变量 , 由于没有结构体名 , 因此后续不可以再定义新的结构体变量 。
4、配合 , 声明结构体的同时为结构体取别名
前面说过 , 使用结构体去定义结构体变量时 , C 需要加  , C++ 不需要 。那么使用结构体的别名去定义变量呢?
答:使用结构体别名去定义结构体变量时 , C 和 C++ 都不需要加  , 加了反而都会报错 , 因为取别名时把连同结构体名称一起包含进去了 。
5、在声明匿名结构体时 , 使用给这个匿名结构体取别名
这种形式声明了一个缺失结构体名的结构体 , 但同时使用为结构体设置了别名 , 所以之后我们可以使用这个别名 , 去定义结构体变量 。
三. 结构体变量的初始化
先弄清楚变量初始化和赋值的区别:
struct Student{char name[20];int age;};int main(){// 变量刚开始创建时给值 , 这个叫初始化struct Student s1 = {"nick", 18};// 变量创建后 , 再对它的值进行操作这个叫赋值strcpy(s1.name, "tony");s1.age = 24;return 0;}
结构体只能被整体初始化 , 不能被整体赋值 , 想要赋值的话只能把成员逐个地取出来再赋值 。
补充:数组也是一样的道理:只能整体初始化 , 不能整体赋值 。如果是字符数组想要整体赋值的话 , 可以使用函数:
本人推测结构体和数组不能被整体赋值的原因是:它们内部空间在逻辑上是独立一块块的 , 所以我们只能对这些独立的空间逐个赋值 , 而不能整体赋值 。
四. 结构体成员的访问方法
我们可以通过变量或变量的地址去访问结构体的成员 。
struct Student{char name[20];int age;};int main(){// 1、通过变量访问结构体成员struct Student s;strcpy(s.name, "张三");s.age = 18;// 2、通过指针访问结构体成员struct Student* p = &s;printf("%s\n", p->name);printf("%d\n", p->age);return 0;}--------结果如下--------张三18
为什么结构体会有两种访问方式?
在函数传参(传值、传址)时 , 会生成临时变量 , 如果要传的结构体变量太大的话 , 传值拷贝出来的临时对象也会很大 , 如果用传地址的方式来传结构体变量地址的话 , 可以很好的节省空间 。