0
点赞
收藏
分享

微信扫一扫

C语言之自定义类型_结构体篇(2)

攻城狮Chova 2023-10-07 阅读 40

目录

结构体传参

结构体实现位段(位段的填充&可移植性)

什么是位段

位段的大小计算 

位段的内存分配

位段的跨平台问题

位段的应用


今天接着我们继续自定义类型结构体。🙂🙂

结构体传参

在我们初阶结构体我们学习过结构体传参的知识。

关于下面代码:

#include<stdio.h>
struct S
{
	int data[1000];
	int num;
};
//结构体传参
//栈区形参开辟一块空间,实参开辟一块空间,很浪费
void print1(struct S s)//形参
{
	printf("%d\n", s.num);
}
//结构体地址传参
//压栈的时候只用开辟四个字节的空间,效率更高
void print2(const struct S* ps)//不安全 -> const 安全
{
	printf("%d\n", ps->num);
}
int main()
{
	struct S s = { {1,2,3,4}, 1000 };//实参
	print1(s); //传结构体 传值调用
	print2(&s); //传地址 传址调用
	return 0;
}

 上面的print1和print2那个好?明显,print2。

结构体实现位段(位段的填充&可移植性)

在上一篇博文我们讲完了结构,这篇我们来谈谈位段。结构会为了效率浪费空间,位段出现就是为了节省空间。

什么是位段

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

  • 位段的成员必须是int unsigned int signed int
  • C99之后,也可以是其他类型,但是基本上都是 int char 整型家族🆗
  • 位段的成员名后边右一个冒号和一个数字。
//位段
struct A
{
	int _a : 2;
	int _b : 5;
	int _c : 10;
	int _d : 30;
};
//结构
struct A
{
	int _a;
	int _b;
	int _c;
	int _d;
};

 一个结构体的某一些成员,它对内存的需求,只是占了给它分配内存空间的一部分吗,用不完。那么此刻我们就可以使用位段,去保证效率的同时节省空间。

位段的大小计算 

#include<stdio.h>
struct A
{
	int _a : 2;
	int _b : 5;
	int _c : 10;
	int _d : 30;
};
int main()
{
	printf("%d", sizeof(struct A));
	return 0;
}

是否和你预期的一样呢?? 

位段的内存分配

到底是怎么开辟的呢?简单来说,就是依次开辟。例如先开辟一个字节空间(8个比特位),不够的话再开辟1个字节的空间,依次下去...

那不同编译器有所差别,又有很多不确定因素。即便这样,我们还是可以探究一下在VS上到底是怎么使用的?

//一个例子
struct S
{
char a:3;
char b:4;
char c:5;
char d:4;
};
struct S s = {0};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
//空间是如何开辟的?

我们验证发现,果然等于3。  

有人说可能是巧合,或者从高到低地址也是这样的。那我们调试验证一下。

 

调试,&s之后,在内存窗口。

位段的跨平台问题

  • 跟结构体相比,位段可以达到同样的效果,同时可以很好的节省空间,存在跨平台问题。 

位段的应用

位段应用在网络工程等方面。有兴趣可以下去了解一下

✔✔✔✔✔最后,感谢大家的阅读,若有错误和不足,欢迎指正!

下篇博文我们继续自定义类型&枚举&联合。

代码------→【gitee:唐棣棣 (TSQXG) - Gitee.com】

联系------→【邮箱:2784139418@qq.com】

举报

相关推荐

0 条评论