C语言 结构体学习笔记

一,结构体的定义

(1)常规方式

结构体内可以定义各种元素,包括:常规变量(字符,整形,浮点),数组,指针,以及结构体,其中结构体有多种的定义方式,以下是结构体的三种常规定义方式。

(2)匿名结构体

当结构体在声明时 Struct后面不再有结构体名字时,称为匿名结构体,此时需要在结构体最后加上结构体变量的名字,(声明,由于只有定义结构体的名字,因此该结构体没有变量名字,因此该类型结构体为一次性结构体,只能通过定义的名字使用一次)

其中由于进行指针操作需要两个相同的变量类型,但两个不同的结构体不能进行指针操作,因为不同的结构体被看作为不同的变量类型。

如上图所示,不可以进行 *psa = sa。因为两个不同的结构体是两个不同的变量类型。

(3)结构体的自引用

//结构体指针自引用的正确用法
struct A
{
    int a;
    sturct *A next;
}

如上在链表结构中使用的结构体自引用,在结构体自引用时需注意如果结构体通过匿名定义,则不可以使用自引用,根据编译器的执行逻辑,在运行到结构体时,还未定义NODE*,因此指针找不到NODE*.

                                                

(4)结构体变量的初始化

二,结构体的内存对齐

结构体在内存中的位置与内存对齐有着关联,其中内存对齐要根据对齐数来进行判断,如某编译器的默认对齐数为8,int型大小为4,则结构体的成员变量要对其到4的整数倍地址处,char则需要对其到1的整数倍地址处。而一个结构体的最大容量为成员间最大对齐数的整数倍,在嵌套了一个结构体时,则需要对其到嵌套结构体内的最大对其数的整数倍处,最大容量为嵌套结构体的最大对齐数的整数倍。(其中数组的最大对齐数不是数组的存储容量,而是数组的类型的对齐数例如 char i[【】为1 int i【】为4)

Q:为什么要使用结构体的内存对齐?

本质上是使用牺牲空间换取时间的一种做法,因为在数据线每次访问内存时,为了提高数据线的访问效率,让内存线通过整数倍的方式来进行访问

tips:通过代码的写法也可以节省空间,如下图所示

s1结构体变量:char首地址比较后1个对齐数,int比较后四个对齐数,char比较后一个对齐数,因此100011111000使用了12个字节(1代表使用的空间,0代表浪费的空间)

s1结构体变量:char首地址比较后1个对齐数,char比较后一个对齐数,int比较后四个对齐数,因此11001111使用了8个字节(1代表使用的空间,0代表浪费的空间)

修改对齐数

通过#pragma修改默认对齐数位,可以进一步节省空间

offsetof(计算结构体首位置编译量的宏)分析结构体中的成员地址的首地址距离结构体首地址的距离,单位字节。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值