结构体的理解

本文详细介绍了C语言中结构体的概念,包括其声明、创建方法、成员访问、初始化以及对齐规则。结构体是描述复杂对象的有效工具,展示了封装思想的应用。同时讨论了对齐的重要性,以及如何通过pragmapack调整对齐策略。
摘要由CSDN通过智能技术生成

结构体属于自定义类型,用于描述复杂对象

例如最典型的描述一个学生对象:有名字、学号、性别、年龄、年级等多个属性,使用结构体定义非常方便。这也是封装思想的典型应用。

一、结构体的声明与创建:
结构体是一些值的集合,这些值称为成员变量,每一个成员变量可以是不同的类型
定义格式:
(struct关键字不可省略)
struct 自定义的结构体类型名字{
member-list;
成员变量;
}变量列表(称为结构体变量,可有可无);//只有创建全局结构体变量才使用

介绍下结构体的声明1,首先使用关键字struct,他表示接下来是一个结构体。
2;后面是一个可选的标志(XXXX),它是用来引用该结构体的快速标记。因此我们以后就会可以这样创建数据对象

3;接下来就是一个花括号,括起了结构体成员列表,及就是每个成员变量,使用的都是其自己的声明方式来描述,用分号来结束描述;
列如;char title[MAXTITL];字符数组就是这样声明的,用分号结束;
注意;其中每个成员可以使用任何一种c数据结构甚至是其他的结构体,也是可以的;

1、定义方式一:
而后直接在声明结构体花括号后面直接创建,//这种方式创建的结构体属于全局变量

这个时候就相当于直接创建了两个该类型结构的全局变量stu1和stu2


2、定义方式二
用struct + 结构体类型名 + 结构体变量名
  例如:struct student s;

示例:


3、用typedef重定义类型:
此时的Student是一个该结构体的类型,可以理解为跟int、double一样,用于声明变量

(而事实上类型的声明本质上是决定访问地址的多少的问题)


对于结构体的初始化使用{}大括号
创建结构体变量,有两种方式:
一种是正常的顺序定义,即必须和定义结构体类型的顺序相同
还有一种是乱序定义,可以使用.引用符号进行定义

访问结构体成员;

结构体就像一个超级数组,在这个超级数组内,一个元素可以是char类型,下个元素就可以是flaot类型,再下个还可以是int数组型,这些都是存在的。在数组里面我们通过下标可以访问一个数组的各个元素,那么如何访问结构体中的各个成员呢?
用结构成员运算符点(.)就可以了;
结构体变量名.成员名;
注意,点其结合性是自左至右的,它在所有的运算符中优先级是最高的;

什么叫结构体对齐?

第一个成员变量存储在与结构体初始地址偏移量为o的地方
其他成员要存储在某个数字(对齐数)的整数倍的地址//这个对齐数是该成员自身的对齐数

结构体的内存必须是最大对齐数的整数倍,在这个例子中,结构体内存大小本应该是5,但不是4的整数倍,于是就变成了8.

什么是对齐数?(每一个成员的类型占据的字节大小就是该成员的对齐数,所以每一个成员的对齐数就是数据类型大小,而后再将所有成员的对齐数进行比较,取较大的为对齐数。还要和默认的对齐数进行比较,取较小值)
对齐数:编译器默认的对齐数 与 该成员大小的较小值,而VS的默认对齐数是8
(注意:linux(gcc)编译器没有默认对齐数,其对齐数就是成员自身的大小)

2、为什么要对齐?

空间换时间
由于机器的环境不同,或者要访问某一个数据时,本质上是访问某个地址,其每一次访问的字节数是固定的。
比如一个结构体的第一个数据是字符,而第二个数据是一个整型类型。假设我们要访问第二整型数据,
如果在结构体存储时不对齐,那么该结构体的地址是5个字节,那么我们需要访问两次,因为第一次只能访问四个字节,
而第二个数据是整型是第二位到第五,还要再访问一次4字节才能将第二个整型数据全部拿到。


可以自己修改默认的对齐数:
#pragam pack(设置的默认对齐数大小)//当设置为1时,相当于没有对齐,因为每一个位置都是1的倍数
该句在代码中的书写意义是,从写下该句开始之后改变默认对齐数
如果要取消设置,返还系统默认设置,则再写一次
#pragam pack()


offsetof (type,member);//是一个宏,可以直接使用,作用是计算结构体成员相对于起始位置的偏移量,返回值即偏移量


  • 14
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值