结构体(struct)

本文介绍了C语言中的结构体,包括结构体类型声明、变量创建与初始化,以及结构成员的访问操作。重点讲解了内存对齐规则,通过示例说明结构体大小计算方法,并解释了内存对齐背后的目的。
摘要由CSDN通过智能技术生成

        C语言提供了许多内置类型,如:char、int、double等,假设我想描述一本书,这时单一的内置类型是不行的。因为要描述一本书需要作者、定价等。所以C语言为我们提供了结构体这种自定义的数据类型。下面我来介绍一下结构体。

目录

结构体类型的声明

结构体变量的创建和初始化

结构成员访问操作符

结构体内存对齐*


结构体类型的声明

        结构体其实就是一些值的集合,这些值被称为成员变量。结构体的每个成员可以是不同类型的变量。

        结构体的语法定义如下:

0f27ddb2798e45e7bab8c4cfe979136b.jpg

  • struct是结构体的关键字
  • tag:是结构体名
  • member-list:是成员列表
  • variable-list:是变量列表(这里可以不创建变量)
  • 最后的;不要忘了

结构体变量的创建和初始化

        变量创建:

cc31a5bb1148484792cfcc5ba25f2488.png

        初始化时要按照结构体成员的顺序来进行初始化(其实也可以不按照顺序这个以后再说):

577873b61ed747aab9c401b55f4c19ab.png

结构成员访问操作符

        如果是结构体变量用点操作符(.),如果是指向结构体的指针用(->)。

712b50aad67043ca824136198c72151e.png

        在上面我说了初始化也可以不按照结构体成员的顺序来初始化那要怎么写呢?

fb0ba3f4385f4f4db7a1016752e204cd.png

结构体内存对齐*

        结构体的大小并不是成员一共有多大它就多大,它有着自己的一套规则。

  • 1. 第一个成员在与结构体变量偏移量为0的地址处。
  • 2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

            对齐数 = 编译器默认的一个对齐数与该成员变量大小的较小值。

            - VS 中默认的值为 8。

            - Linux中 gcc 没有默认对齐数,对齐数就是成员自身的大小。

  • 3. 结构体的总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
  • 4. 如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

        

        我来给大家举个栗子,方便大家理解(我用的是VS)。

7308d7a1f0dc4aafb6f5512285d304c0.png

蓝背景→(最大)对齐数

红背景→与结构体首地址的偏移量

      a是char类型占1个字节。因为a是第一个成员,所以a存在结构体地址的首位(第一个成员不用对齐,但有对齐数)。

     b是int类型占4个字节小于VS规定的8个字节,故对齐数是4个字节。因为1不是4的整数倍所以向后找,因为44的整数倍,所以在4处开始存。

     c是char类型占1个字节小于VS规定的8个字节,故对齐数是1个字节。因为81的整数倍,所以在8处开始存。

     在这3个中最大对齐数是4个字节,因为9不是4的整数倍所以向后找,因为124的整数倍,所以总大小是12个字节。

图例如下↓

f338c6e33f214921b5e2ddc2a42e4ce0.png        

        那如果是嵌套的结构体该怎么算呢?其实也大差不差。

41d8fc4ebb46451e829e1741e7c3fe26.png

     前面的我就不过多赘述了。

     当走到struct S2时,struct S2中最大对齐数是4个字节,因为1不是4的整数倍所以向后找,因为44的整数倍,所以在4处开始存放struct S2的第一个成员,其它和之前一样。

      在确定结构体总大小时,要看所有对齐数,并找到最大的对齐数。在这个中最大对齐数是4个字节,因为164的整数倍,所以总大小的16个字节。

     图例如下↓

      88d40844ef8d435fa4ac1b6f11c054b6.png

        给大家出一道题:

#include <stdio.h>

struct S
{
	char a;
	char b;
	int c;
};

int main()
{
	printf("%zd", sizeof(struct S));
	return 0;
}

     因为a,b都占1个字节故顺着存,2不是4的整数倍所以向后找,遇到4时开始存。因为最大对齐数是4个字节,且84的整数倍,故结构体总大小是8个字节。 

    怎么样写对了吗?

        我举的第一个栗子和这个练习相比不难发现数据是一样的只是顺序不同,但是结构体的大小居然不同!

        事实上,如果同一类型的数据放在一起就可能会减少内存。

        为什么要存在内存对齐呢?事实上这是牺牲空间时间的做法。

        好了讲到这儿就差不多讲完了,希望你能有所收获。如果存在错误地方请及时指出,如果还有什么不懂的地方可以私信我,如果觉得不错那就点点赞吧!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值