自定义类型--结构体(C语言)

结构体的声明

结构体我们并不陌生,在许多情况下都有结构体的身影,这是因为结构体不仅能存放多个元素,还可以存放不同类型的元素这是数组所无法匹及的功能,因此他的应用范围很广,接下来我们开始了解结构体的声明,具体的列子为struct BOOK{ char book[20]; int BOOKs ; char author[20] … }b1; 以上的声明所表达的意思是:我们自定义了一个类型为“struct BOOK"的变量,变量名叫做”b1",其中包含的元素有名为book和author的字符数组还有一个BOOKs的整型变量。当我们在主函数中需要用到时开始对b1进行每个变量的赋值:b1={“…“,”…“,”…“}以这种形式进行每个元素的赋值,如果在不按照顺序的情况下进行赋值:b1={book=”…“,BOOKs=”…“,author=”…"};标注每个变量名再进行赋值。

结构体的对齐类型

意思为在结构体中数据存储的类型与普通的存放方式大有不同。而结构体的内存的存放方式为内存对齐的方式。在将具体的对齐规则前我们要先知道一个概念:偏移量:指该数据存放的地址距离指定地址的字节大小。现在再来开始讲对齐规则:1.第一个成员要与结构体变量的起始地址相同且偏移量为零。2.其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。对⻬数=编译器默认的⼀个对⻬数与该成员变量⼤⼩的较⼩值.VS 中默认的值为 8, Linux中gcc没有默认对⻬数,对⻬数就是成员⾃⾝的⼤⼩。3.结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的整数倍。4.如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。需要注意的是我们在计算完所有元素的内存空间时,容易忘记第三条规则,一定要查看结构体的大小是是否符合时最大对齐数的整数倍,否则要在多出空间直到时最大对其数的整数倍。

结构体传参

结构体的传参分为两种:传值调用和传址调用。二者的不同之处我们已经十分熟悉,区别就在于一个是无法改变原本的元素的大小,另一个是可以改变原有元素的大小。其形式与其他无异(就拿上文举例的结构体说明):print(b1)(print为我所创造的函数,将变量b1中的每个元素的值传进去,其函数的声明为:void print(struct book s);传址调用为:print(&b1);声明为:void print(struct book* p1);所以无论是传值调用还是传址调用都与一般的形式无异。

结构体位段

如果说结构体对齐规则是为了牺牲空间的大小来调高程序的运行速度(系统在排查内存时一般以四字节或者八字节大小进行排查,如果一个整型存放的地址是奇数位,那么系统会面临排查不彻底的情况,就会再次排查一遍但浪费了时间,所以对齐规则是为了让系统尽可能的一次就可以排查结束不会浪费时间)那么结构体位段则是为了尽可能的节省空间。结构体位段的表现方式为:列如char a:3;意思为在结构体中的这个名字为a的字符变量的内存空间中占用3个bit位(一个字节为8个bit位,可见对空间的利用率足够高),但是也有不确定因素,因为我们无法得知这3个bit位的数据是在一个字节中是从左向右排序还是从右向左排序,这要靠编译器本身进行抉择,同时一个字符的大小为一字节即8个bit位,存放时必将会缺失部分数据,于是我们将数据从低位到高位一次排放,直到排满要求的空间为止。第二个不确定的因素是:一个字节可能会排放多个元素,当剩余的空间不足以继续排放时,是选择先排满再跳转到下一字节还是直接略过来到下一字节进行排放,这也由系统决定。同时位段无法进行取地址,因此无法完成传址调用,但可以用scanf函数进行打印。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值