struct 结构体类型的本质是 数据类型 ,既然是数据类型,就是用来创建变量,而创建的这个变量其实是 变量的集合,是结构体里面成员变量的集合
struct Test
{
int a,b;
};
struct Test t
t.a = 1;
t.b = 2;
//意味着,结构体变量是一个变量的集合,这里的 t 是一个变量的集合,在这个集合里面,有 2 个变量 a和b
这里的 t 是变量,既然是变量,它的本质是一段内存,而 t 又是变量的集合,所以说这段内存被分为了 2 部分,一部分是a 成员变量所占用的内存,一部分是b 成员变量所占用的内存,因此 a 和 b 占用独立的内存
ps -> id = 1; //利用指针,通过箭头 操作符,来访问对应的成员变量,这里是将 id 赋值为 1
这个类型都没定义,怎么不会报错?
因为在整个程序中没有用到 struct Student 这个类型名,也没有用到 Stu 这个 类型名,
仅仅是声明 struct Student 这个类型仅仅可以使用这个名字 Stu 来代替
因为 s 所属的类型没有定义
没有错误和警告,意味着通过指针来访问结构体成员的时候,要使用箭头 -> 操作符
这里的 ps 就是指向 s 的,通过 ps 这个指针来访问成员变量,来改变成员变量,最终改变的是 s 这个结构体变量了,
如果说省略了类型名,那么整个类型就长这个样子
struct {int a, b} 这样写就是一个具体的结构体类型了
通过结构体类型可以定义结构体变量,
struct {int a, b} noname;
这里的 noname 是一个变量,这个变量的类型是 struct {int a, b}
因此,这样写肯定是正确的
noname.a = 1;
noname.b = 2;
这种操作叫 : 定义无名结构体的操作
这里肯定 error ,在定义具体变量之前,必须给出类型的完整定义
编译不过,因为必须 在它定义变量之前出现,否则报错
使用了 g_pt 这个全局指针 指向了main 函数中定义的局部变量
实验证明了: 声明和定义不同的, 声明之后只能创建对应的指针变量,不能够创建具体的变量
struct { int a, b; } 这个整体就是一个类型,通过这个类型就可以创建变量
这里的v2 和 v1 是同一种类型吗?
错误答案 : 一模一样的无名结构体,所以是相同的类型
正确答案 : 无名结构体类型总是互不相同的类型,即便看起来一模一样,但本质上是互不相同的类型,也就是说他们互不兼容,不能够相互的赋值
这样子 想要用v2 给v1 赋值是错误的
用无名结构体定义变量 ,定义了2个普通变量,一个指针变量,从视觉效果看,这3个无名结构体 是一模一样的,所以很容易误认为是一模一样的类型,
视觉效果上的结论 : v1 和 v2是同样类型的变量, pv是可以指向 v1 ,可以指向 v2
事实上v1 ,v2和pv,没有任何关系
error : v1 和 v2 的类型不兼容
实验结论 :所有的无名结构体类型即便视觉效果上看起来一模一样,也是不同的类型
位域 : 是一种结构体类型,是一种自定义类型
#include <stdio.h>
#include <string.h>
struct BW
{
unsigned char a : 4;
unsigned char b : 2;
unsigned char c : 2;
};
int main()
{
struct BW bw = {0}; //定义了一个变量 bw,并且将这个变量初始化为0,这里的初始化为 0 ,指的是把每一个 bit 位都初始化为0.
bw.a = 10;
bw.b = 4; //4 大于 b 所能表示的最大值,因此赋值后 b 回转到 0
bw.c = 3;
printf("sizeof(struct BW) = %d\n", sizeof(struct BW));
printf("bw.a = %d\n", bw.a);
printf("bw.b = %d\n", bw.b);
printf("bw.c = %d\n", bw.c);
return 0;
}
位域 只是结构体的特殊玩法,本质还是结构体,f 作为一个浮点类型结构体成员显然正确。
这个类型占多少字节?
总结 :
struct 结构体类型当中的成员,是占用独立的内存,因为struct 结构体变量其实就是一个包,在这个包里面有各种各样的成员变量,而这些各种各样的成员变量是分别占用内存的,他们是独立的