【c基础】数据类型--结构和联合

来源:互联网 发布:复制信息打开淘宝 编辑:程序博客网 时间:2024/05/22 06:54

一、结构

聚合数据类型能够同时存储超过一个的单独数据。c提供了两种聚合数据类型:数组和结构
数组是相同类型的元素的集合,它的每个元素是通过下标引用或指针间接访问来选择的。
结构可以存储不同的类型值,这些值为它的成员,成员是通过名字访问的。

结构声明
eg.1: struct SIMPLE {
int a;
char b;
float c;
};
struct SIMPLE x, y[20], *z;

eg.2: typedef struct {
int a;
char b;
float c;
} Simple;
Simple x, y[20], *z;

访问结构成员:
eg:x.a;// 直接访问,x是结构名

z->a;// 间接访问,z是指向结构的指针

结构初始化类似与数组的初始化

结构的存储分配:编译器按照成员列表顺序给每个成员分配内存,只有当存储成员时需要满足正确的边界对其要求时,成员之前才可能出现用于填充的额外内存空间。

通常情况下,作为函数参数的结构,参数应该设为结构指针,若不改变结构成员,使用关键字const。
eg:void f( register Simple const *z )

二、联合

联合的声明和结构类似,但行为方式却和结构不同。联合的所有成员引用的是内存中的相同位置。

联合的长度就是它最长成员的长度。当成员长度差异大时,更好的方法是在联合中存储指向不同成员的指针而不是直接存储成员本身。(先存指针,用时再动态分配内存以节省内存空间。)

初始化:必须是联合的第一个成员类型,而且必须位于花括号里。
eg:unio  {
inta;
floata;
charc[4];
}  x = { 5 };     
// x.a初始化为5

三、总结

在结构(struct)中,不同类型的值可以存储在一起。结构中的值称为成员,他们是通过名字访问的。结构变量是一个标量,可以出现在普通标量中可以出现的任何场合。


结构的声明列出了结构包含的成员列表。不同的结构声明即使他们的成员列表相同也被认为是不同类型的。结构标签是一个名字,它与一个成员列表相关联。你可以使用结构标签在不同的声明中创建相同类型的结构变量,这样就不用每次在声明中重复成员列表。typedef 也可以用于实现这个目标。


结构的成员可以使标量、数组或指针。结构也可以包含本身也是结构的成员。在不同的结构中出现同样的成员是不会引起冲突的。你使用点操作符访问结构变量的成员。如果你拥有一个指向结构的指针,你可以使用箭头操作符访问这个结构的成员。


结构不能包含类型也是这个结构的成员,但它的成员可以是一个指向这个结构的指针。这个技巧常常用于链式数据结构中。为了声明两个结构,每个结构都包含一个指向对方的指针的成员,我们需要使用不完整的声明来定义一个结构标签名。结构变量可以用一个由花括号包围的值列表进行初始化。这些值的类型必须适合它所初始化的那些成员。


编译器为一个结构变量的成员分配内存时要满足它们的边界对齐要求。在实现结构存储的边界对齐时,可能会浪费一部分内存空间。根据边界对齐要求降序排列结构成员可以最大限度地减少结构存储中浪费的内存空间。sizeof 返回的值包含了结构中浪费的内存空间。


 结构可以作为参数传递给函数,也可以作为返回值从函数返回。但是,向函数传递的一个指向结构的指针往往效率更高。在结构指针参数的声明中可以加上const 关键字防止函数修改指针所指向的结构。


位段是结构的一种,但它的成员长度以位为单位指定。位段声明在本质上是不可移植的,因为它涉及许多与实现有关的因素。但是,位段允许你把长度为奇数的值包装在一起以节省存储空间。源代码如果需要访问一个值内部任意的一些位,使用位段比较简便。


 一个联合的所有成员都存储于同一个内存位置。通过访问不同类型的联合成员,内存中相同的位组合可以解释为不用的东西。联合在实现变体记录时很有用,但程序员必须负责确认实际存储的是哪个变体并选择正确的联合成语以便访问数据。联合变量也可以进行初始化,但初始化值必须与联合第1个成员的类型匹配,而且它必须位于一对花括号里面。在联合中存储指向不同成员的指针而不是直接存储成员本身,可以解决内存浪费问题。


想函数传递结构参数是低效的,应该用指向结构的指针传递参数。把结构体标签声明和结构的typedef 声明放在头文件中,当源文件需要这些声明时可以通过#include 指令把他们包含进来。把位段成员显示声明为signed int 或unsigned int 类型。

原创粉丝点击