结构体具体知识

本文详细介绍了C语言中结构体的概念、使用方法,包括初始化、指针操作以及结构体的对齐规则。同时探讨了位段的特性,如何高效利用内存空间,以及注意事项如跨平台迁移问题。
摘要由CSDN通过智能技术生成

在C语言中,结构体是我们经常使用的一个自定义变量类型,为了能够合理的理解和利用结构体,我们有必要对结构体的知识进行一次系统的整理。

首先,结构体是什么?当我们把一个学生(student)作为一个变量进行描述的时候,我们会发现一个人是有名字,年龄,性别,身高等等元素的,一个变量无法穷举他所有的内容。这时,将这些需要的元素放到一个自定义变量中,就可以用一个Struct变量描述这些数据了。

struct student
{
	char name;
	int age;
	int height;
}a;

如图所示,我这串代码就是建立了一个student 类型的结构体,并往里面放了3个数据,分别是类型为char的name,int类型的age,int类型的height,并在最后建立了一个student类型的变量a。而对于初始化一个结构体变量我们就可以这样做。

	struct student s = { "张三",20,169 };
	struct student b = { .age = 20 ,.heignt = 169,.name = "张三" };

第一种方法是简单快捷的直接利用结构体内部的顺序进行初始化,从上往下依次赋值。第二种则是通过特定的指向进行初始化,利用.操作符,可以直接指向该结构体的具体参数位置。而对于结构体的内部参数改变,其实我们还有第三种方法,指针操作。

struct student * p = &b;
p->age = 19;

利用指针来控制结构体中的数据其实更为方便快捷。

在声明结构体的时候,可以不完全声明,也就是不给他一个名字,如上文的结构体中就给了一个student 的名字。但是,全局代码中,最多只能存在一个未被定义的结构体类型。否则编译器会报错,他不知道你后面再创建一个变量到底是第一个未定义的结构体还是第二个未定义的结构体。

在结构体中,如果我们想要包含一个类型为结构体本身的成员,不可以直接包含,如果直接包含,会导致该结构体的变量无限变大。那如果我们还是想要包含这个结构体,或者说,想要有办法去找到该结构体,那怎么办呢?这时候,我们就要想到yyds,指针了。

众所周知,指针的大小永远只有4/8个字节,相比于无限叠加的结构体类型已经是非常小的了。通过查询指针的地址,我们可以直接找到另一个结构体,这是一个非常节省空间的方法,very good.并且,对于想要结构体传参,直接传过去一个结构体也是不合理的,太大了。传过去一个地址是非常好的主意。

对于结构体的对齐规则,也是我们需要掌握的,那么我们才可以真正的理解结构体内部的空间内存分布状态。

1.结构体的第一个成员对齐到结构体变量起始位置。

2.其他成员需要对齐到对齐数的整数倍的地址处。对齐数是编译器默认的一个对齐数(在VS中是8)与该成员变量大小的较小处值。

3.整个结构体的总大小为最大对齐数的整数倍。这里的最大对齐数指的就是结构体中所有成员的对齐数中的最大值。

4.如果结构体中有结构体,那么二次结构体的成员对齐到结构体成员中最大对齐数的整数倍数,二次结构体的大小就是最大对齐数的整数倍。

内存对齐是一种用空间来换取时间的妥协手段,为了使代码更加高效的进行运行,我们可以进行合理的代码设计,使得每一个字节尽量的被占满,那么该代码就是高效的。如果我们想要修改默认的对齐数,我们可以通过#pragma这个预处理指令来改变编译器的默认对齐数。

既然已经讲到结构体了,那就必须讲讲位段了。首先使用位段的对象必须是int 或者 unsigned int类型的的数据,并且其格式如下图所示:

struct student
{
	char name;
	char age:2;
	char heignt:3;
    char face:6;
}a;

在上述代码中,我在两个int类型数据后面加上了冒号与数字,那么这个student就变成了一个位段类型的数据了。数字代表的是该变量最大能占几个比特位,比如上图的age,现在最多只能占2个比特位,如果我们给age一个9,解析成2进制就是1001,但是在读取时只会读到01,于是该age就是读到1这个数据而非9.然后在第二个字节里面,这个就是占到2个比特位,对于第三个数据heignt发现第二个字节里面还有6个比特位,所以就继续使用。再看后面的face变量,由于第二个字节只剩下3个比特位了,无法存入,于是就打开第三个字节并存入数据。所以这个student的结构体只占用了3个字节的大小。

这个方法能十分高校的利用内存空间,但也有其弊端。第一个弊端是无法通过指针去修改内部变量数据。因为指针最多指到字节处,无法指比特位的地方。第二个弊端是不易于跨平台的迁移,因为各个平台对于位段与int类型的数据的定义不是完全相同的。

以上,就是我对结构体和位段的学习和理解,谢谢您的观看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值