C和指针(七)结构、联合

结构
1,聚合数据类型能存储超过一个的单独数据。
1)数组是同类型元素的集合,元素通过下标或指针间接访问来选择。
2)结构将不同类型的值存储在一起,每个结构成员都有自己的名字,通过名字访问。

2,声明结构时,必须列出所有成员的类型和名字。
1)省略标签字段的两个结构声明即使成员列表完全相同,编绎器也会当作不同的类型。
2)标签字段允许为成员列表提供一个名字,可以在后续声明中使用。
3)标签允许多个声明使用同一个成员列表,创建同一种类型的结构。
4)声明结构还可以使用typedef创建新的类型,与结构标签效果相同,但不是结构标签名而是个类型名。

3,结构变量的成员通过点操作符访问,指向结构的指针通过->操作符访问结构成员。

4,结构内部不允许该结构本身的成员,允许结构内部包含指向该结构本身的指针。
1)编绎器在结构的长度确定之前已经知道指针的长度,所以指针类型的自引用是合法的。
2)当需要声明相互存在依赖的结构时,至少有一个结构在另一结构内部以指针形式存在。
3)先不完整声明一个结构标签的标识符,再在另一结构中声明指向该结构的指针,最后再完整声明该结构,在该结构中声明指向另一结构的指针。

5,结构的初始化与数组类似,使用逗号分隔的嵌套初始值列表初始化各个成员,如果初始值不够,剩余结构成员使用缺省值初始化。

6,结构在内存中的存储,编绎器按照成员列表顺序给每个成员分配内存,当需要满足边界对齐要求时,成员间会出现用于填充的额外内存空间。
1)系统禁止编绎器在结构的起始位置填充字节满足边界对齐要求,所有结构的起始存储位置必须是结构中边界要求最严格的数据类型所要求的位置。
2)结构变量后面还可能填充额外内存空间,因为相同类型的第二个结构变量起始存储位置也必须满足边界对齐要求。
3)在结构声明中将边界要求最严格的成员放在前面,对边界要求最弱的成员最后出现,可以最大限度地减少因边界对齐带来的空间损失。
4)也可以将相关结构成员存储在一起,提高程序的可维护性和可读性,不计较边界对齐造成的内存损失。
5)sizeof操作符得到结构的整体长度,包括边界对齐填充的字节。
6)可使用offsetof宏(定义于stddef.h)确定结构中成员相对结构存储位置的偏移量,参数为结构类型和成员名。

7,结构作为函数参数时,传递一个指向结构的指针比传递结构小,压到堆栈能提高效率,代价是在函数中使用间接访问来访问结构成员。
1)在许多机器上,将参数声明为寄存器变量能进一步提高指针传递方案的效率,函数将压到堆栈中的参数复制到寄存器,供函数使用,如果函数对指针的间接访问超过两三次,使用这种方法节省的时间大大超过参数复制到寄存器指令花费的时间。

结构的位段
1,位段的声明和结构类似,成员是一个或多个位的字段,这些不同长度的字段实际上存储于一个或多个整型变量中。
2,位段成员必须声明为int、signed int、unsigned int类型,成员名后是一个冒号和一个整数,整数指定该位段占用位的数目。
3,signed或unsigned显式声明位段整数,如果位段声明为int类型,编绎器决定解释为有符号数还是无符号数。

4,注意可移植性的程序应避免使用位段。
1)int位段解释成有符号数或无符号数由编绎器决定。
2)编绎器限制位的最大数目为一个整型值长度,运行于32位整数机器上的位段声明可能在16位整数机器上无法运行。
3)不确定位段成员在内存中是从左向右分配还是从右向左分配,当声明两个位段,第二个位段无法容纳于第一个位段剩余位时,编绎器可能将第二个位段放在内存下一个字,也可能直接放在第一个位段后面。

5,位段可节省存储空间,并且方便访问一个整型值的部分内容。
1)任何使用位段实现的任务都可以使用移位和屏蔽实现,目标代码中这两种方法没有区别。
2)位段简化了源代码,但移值性较弱。

联合
1,联合声明和结构类似,但联合的所有成员引用的是内存中相同位置。
1)不同时刻在相同位置存储不同的东西。
2)成员引用的位相同,区别在于每个成员的类型决定这些位如何解释。

2,联合各个成员具有不同的长度,联合的长度就是最长成员的长度。
1)当成员长度相差较大时,可在联合中存储指向不同成员的指针,避免内存浪费。

3,联合初始化值必须是联合第一个成员的类型,由初始值列表提供。

总结
1,在结构中,不同类型的值存储在一起,结构成员通过名字访问。
1)结构声明列出成员列表,不同的结构声明即使成员列表相同也认定是不同的类型。
2)结构标签与成员列表相关联,可以使用结构标签在不同位置声明相同类型的结构变量,typedef也可以实现这个目标。
3)结构的成员可以是数组或指针,甚至可以是其他结构。
4)在不同的结构中可以有相同的成员名,使用点操作符访问结构变量的成员,指向结构的指针可以使用箭头操作符访问结构成员。
5)结构不能包含自身结构类型的成员,但可以声明指向自身结构类型的指针,常应用于链式数据结构中。
6)结构变量可以使用初始值列表进行初始化,值的类型必须适合初始化的成员。

2,编绎器为结构变量成员分配内存时要满足边界对齐要求,实现结构存储边界对齐时会浪费内存空间,根据边界要求降序排列成员可以最大限度减少内存空间的浪费,sizeof包含了浪费的内存空间。
3,位段是结构的一种,成员长度以位为单位指定,位段声明本质上不可移植。
4,位段允许将长度为奇数的值包装在一起节省存储空间,源代码如果要访问值内部任意位时,使用位段比较方便。

5,联合的所有成员存储于同一个内存位置,通过访问不同类型的联合成员,内存中相同的位组合解释为不同的东西。
1)联合在实现变体记录时很有用,但需要确认实际存储的类型选择正确的成员访问。
2)联合变量初始化时初始值必须与联合的第一个成员类型匹配。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值