自定义类型——结构体

一·结构体类型创建和初始化(前面有提)

结构体:
1.指针的时候用->
2.变量的时候用.

//定义一个学生
struct stu
{
char name[20];
int age;
char id[20];
};
int main()
{
struct stu s={"danika",18,"2023001"};//默认顺序
struct stu x={.id="2023002",.name="jack",.age=19};//指定顺序
return 0;
}

结构体的特殊声明:
在使用结构体时,可以不完全声名(匿名结构体)

struct
{
 int a;
 char b;
 float c;
 }
struct
{
 int a;
 char b;
 float c;
}a[20], *p;

此时是省略了结构体标签,在上面的基础上,

p=&x;

就不对了,是因为编译器会把上⾯的两个声明当成完全不同的两个类型,所以是非法的。匿名的结构体类型,如果没有对结构体类型重命名的话,基本上只能使用一次。(温馨提示:以后尽量少用匿名结构体)

二·结构体的自引用

在结构中包含⼀个类型为该结构本⾝的成员是否可以呢?
答案是可以,但是不可以直接引用,否则在计算sizeof(结构体)时就结构体套结构体,无穷尽了,不符合。
可以运用指针,指向该结构体:

struct note
{
int arr[10];
struct note*next;//这样就可以
};

也可以对结构体重命名后使用自引用:

typedef struct Node
{
 int data;
 struct Node* next;
}Node;

三·结构体内存对齐

1.在这里插入图片描述
在这里插入图片描述

VS默认对齐数:8;
Linux中 gcc 没有默认对齐数,对齐数就是成员自身的大小。
2.举例
在这里插入图片描述

在这里插入图片描述
(会有一些区域用不到浪费了)
总体来说:结构体的内存对齐是拿空间来换取时间的做法。
如何既满足对齐,又节省空间?–>
让占⽤空间小的成员尽量集中在⼀起,如上图s2
3.修改默认对齐数

#pragma pack(1)//设置默认对齐数为1
#pragma pack()//取消默认的对齐数,还原为默认

四·结构体传参

在这里插入图片描述
两种方式,但传入地址的那种更好:
1.函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。
2.如果传递⼀个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。
3.如果担心传地址改变实参,可在形参前加const。

五·结构体实现位段

在这里插入图片描述
在这里插入图片描述
开辟完后,为方便理解,可以规定在每个空间从右往左排,如果剩余的空间不够下一个应用,就浪费,继续开辟
2.举例

struct S
{
 char a:3;
 char b:4;
 char c:5;
 char d:4;
};
struct S s = {0};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;

在这里插入图片描述
char类型,一个字节一个字节开辟,a占3个bit,b占4个,以此类推。
所以就算s.a为10,二进制为1010,也只能截3位,010
所以第一个字节中是:0110 010 化为16进制为62.
3.位段的应用(节省空间)
在这里插入图片描述
4.注意
内存中每个字节分配⼀个地址,⼀个字节内部的bit位是没有地址的。
所以不能对位段的成员使用&操作符,这样就不能使用scanf直接给位段的成员输入值,只能是先输入放在⼀个变量中,然后赋值给位段的成员。

struct stu{
 int _a : 2;
 int _b : 5;
 int _c : 10;
 int _d : 30;
};
int main(){
int b=0;
scanf("%d",&b);
stu._b=b;
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值