自定义类型:结构体、枚举、联合(一)

结构体:

1、结构体类型的创建:

补充一点:结构体内部的变量赋不赋值都可以。

2、不完全声明结构体(省略掉结构体标签的结构体)的创建:

 匿名结构体和结构体的区别是:

1、省略掉了结构体标签

2、结构体变量的创建就只有下图这一种方式,这也就意味着,如果你想使用该结构体,则在创建结构体时一定也要写上结构体变量,否则你就没法使用该结构体。

3、创建的结构体的类型与其他结构体的类型不会相同:

 两个结构体的即使成员相同,但是仍不是同一类型。

 3、结构体类型和int、double等类型的区别:

1、结构体类型需要先创建再使用,而int、double等可以直接使用。

2、结构体类型的书写方式为:struct student,而整形、浮点型的书写方式为:int  、double

注释:这里为了方便理解,将结构体标签写为student。结构体标签是在创建结构体时定义的。

4、结构的自引用:

通过在结构体内添加该结构体的指针实现结构体的自引用。

如果写成 下图这样 系统会报错。

原因:如果计算机处理器是32位时,指针大小为4byte,计算机处理器是64位时,指针大小是8byte,在固定的处理器中,指针大小是确定的。但是如果直接在结构体中直接自引用,该结构体的大小是无法确定的,这会使系统崩溃。

5、结构体变量的定义和初始化:(同一标签的结构体只能定义一次)

第一种:

第二种:

 

 第三种:

 

初始化:

 在这里我要额外补充一种结构体成员的赋值:数组

第一种方式是对数组直接初始化,第二种是对结构体初始化,此时如果用{}将数组中的元素括起来时,如果元素个数不足数组会自动补0,如果不用{},数组会自动获取元素,直到数组被填满,才会到下一个成员。(结构体中的成员赋值和初始化时如果都不用{}分割开,则只有第一个成员被填满才会轮到下一个成员)第三种方式,就是使用循环:

补充:在结构体中初始化数组时一定要在[]中写明元素个数,否则系统会报错。

6、结构体内存对齐:

在讲结构体内存对齐前我们先来看两个结构体:

 

 为什么同一个结构体,只是成员的排序不同,他们所占的空间大小却截然不同呢?

这是因为结构体在内存中存储时需要进行内存对齐。

内存对齐规则:

对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS中默认的值为8

1、第一个成员存放起点在与结构体偏移量为零的位置

 2、第二个成员放在第一个成员后面,存放起点为对齐数的整数倍

3、结构体总大小为所有成员中最大对齐数的整数倍。

4、结构体的总偏移量必须是它最大成员字节数的整数倍(包括嵌套的结构体中的最大成员)。如果一个结构体B里嵌套另一个结构体A,结构体A的对齐数就是A中所有成员的对齐数的最大值,存放起点为对齐数的倍数,结构体A所占空间大小为A的大小。(例如:struct B里存有struct A,A里有char,int,double等成员,那A的对齐数是8,存放起点就是8的倍数)。

内存对齐参考资料:(16条消息) c语言结构体嵌套的对齐方式_binbinyantai的博客-CSDN博客_结构体嵌套结构体怎么对齐

为了方便读者理解,我再通过作图向大家展示:

 存储方式:

    虽然用了9个字节就已经将数据存储完了,但是由于此时结构体总大小,不是结构体成员中最大对齐数4的整数倍,所以仍旧会向下偏移,一直偏移到第12个格子。

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

为了提高程序运行效率。 

如何即减少空间损耗,又提高运行效率?

在创建结构体时,将占用空间小的放在一起。

7、如何修改编译器默认对齐数?

可以使用#pragma pack()函数,使用前:

 

 使用后:

8、结构体传参:

 上述两种方式中,如果直接传结构体,系统需要为重新开辟一些空间,接收传过来的结构体。如果结构体较大,会产生空间浪费,通过地址传递,可以避免不必要的空间浪费。

位段

位段的用处:

能够将int、unsigned int、signed int、char型变量(整形家族都可以)在内存中所占空间的大小由字节级改为bit级。

如何使用位段?

1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段
 

 使用位段时确保结构体中所有变量的类型都相同,因为当结构体中所有变量类型相同时,结构体

存储时就不会浪费字节。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值