【C语言进阶篇】自定义类型:结构体(下)

【C语言进阶篇】自定义类型:结构体(下)

 🌈个人主页:开敲

🔥所属专栏:C语言

🌼文章目录🌼 

1. 结构体传参

  2. 结构体实现位段

    2.1 什么是位段

    2.2 位段的内存分配

    2.3 位段的跨平台问题

    2.4 位段的应用

    2.5 位段使用的注意事项

1. 结构体传参

  

                                         上述两种传参形式哪种好?答案是第二种。

  第一种直接传结构体的形式,在形参部分接收也要用到一个结构体,这也意味着需要再次开辟一块空间来存放形参的结构体。而第二种使用指针来接收结构体地址,则不需要额外开辟空间。

  2. 结构体实现位段
    2.1 什么是位段

  首先要知道,位段是基于结构体的。

  位段的声明和结构体类似,但是有两点不同:

①  位段的成员只能是 intunsigned int signed int 或者 char,位段中的成员类型必须相同(在C99中位段的成员也可以选择其他类型)

②  位段的成员名后面跟着一个冒号:  和一个数字(这个数字代表分配给成员的比特位数),比如:

                              

这里的 就是一个位段类型。

 那么 A 所占的内存大小是多少呢?先来看结果:

为什么是8呢,我们紧接着就来讲位段的内存分配。

    2.2 位段的内存分配

    我们前面知道了位段中成员类型的限制,那么这里就可以引出:位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。这里我们举个例子:

这里的大小是 个字节,为什么呢?这就需要我们画图理解位段的内存分配来解决这个问题了:

  

  不难知道,位段在开辟空间时,根据成员的需求开辟空间,不够了再开辟。由此也可以知道,为了代码的可读性和维护性,建议使位段的成员是相同或相似类型。

    2.3 位段的跨平台问题

①  int 位段在不同平台被当成 signed int 还是 unsigned int 是不确定的。

②  位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。

③  位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。

④  当⼀个结构包含两个位段,第二个位段成员比较大,无法容纳于第⼀个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

  总结:位段和结构体相比可以达到相同的效果并且更加节省空间,但是存在跨平台问题。

    2.4 位段的应用

  在网络协议中,就用到了位段,下图是网络协议中,IP数据报的格式,我们可以看到其中很多的属性只需要几个bit位就能描述,这里使用位段,能够实现想要的效果,也节省了空间,这样网络输的数据报大小也会较小⼀些,对网络的畅通是有帮助的。

    2.5 位段使用的注意事项

  位段的几个成员共有同⼀个字节,这样有些成员的起始位置并不是某个字节的起始位置,那么这些位置处是没有地址的。内存中每个字节分配⼀个地址,⼀个字节内部的bit位是没有地址的。
所以不能对位段的成员使用&操作符,这样就不能使⽤scanf直接给位段的成员输入值,只能是先输入放在⼀个变量中,然后赋值给位段的成员。

  

struct A
{
	int a : 2;
	int b : 5;
	int c : 10;
	int d : 30;
};


int main()
{
	struct A sa = { 0 };
	scanf("%d", &sa.b);//这是错误的
	//正确的⽰范
	int b = 0;
	scanf("%d", &b);
	sa.b = 4;
	return 0;
}

                                                  创作不易,点个赞呗,谢谢啦~

    

                                            

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值