第10章——结构和联合

来源:互联网 发布:nginx ip限制 编辑:程序博客网 时间:2024/05/17 18:47

1.C提供了两种类型的聚合数据类型:数组与结构。数据是相同类型的元素的集合,结构把不同类型的值存储在一起。数组的元素通过下标引用或指针间接访问来选择,结构成员通过名字来访问。与数组不同,它并不被替换成一个指针,它属于标量类型,它可以作为传递给函数的参数,也可以作为返回值从函数返回,相同类型的结构变量相互之间可以赋值。

2.struct tag { member-list } variable-list ; struct tag varible variable-list;

    typedef struct { member-list } varible-type; variable-type variable-list;

3.结构的成员可以是标量、数组、指针、甚至是其他结构;

4.结构成员的直接访问:是通过点操作符(.)来访问的。结构成员的间接访问是通过(->)操作符来访问

   struct tag s ; s.a ; struct tag *p = &s ; (*p).a <=> s.a <=> p->a.

5.结构的自引用:自引用不能是本身结构的完整,可以是指向这种类型结构的指针,事实上它指向的是同一种类型的不同结构;自引用时需写上标签部分

6.不完整声明:结构相互依赖:struct B; struct A {struct b *partner;}; struct B { struct A *partner;}

7.结构的初始化与数组类似,可用列表进行初始化

8.结构、指针与成员:typedef struct { member-list; } Ex; Ex x ; Ex *px = &x ;*px + 1 ; *(px + 1) ;*px ; px -> member-list1 ;

9.结构的存储分配:对于不需要满足边界对齐时,结构成员列表一个接一个的存储在内存中,当要满足边界对齐时,成员之间可能出现用于填充的额外内存空间;如果需要节省空间,可以在声明中对成员列表重新声明,让那些对边界要求最严格的成员首先出现,对边界要求最弱的最后出现,然后可以用注释来弥补可读性的缺失。sizeof可以得出一个结构的整体长度,包括因边界对齐而跳过的那些字符,如果必须确定结构中某个成员的实际位置,应该考虑边界对齐因素,可以使用offsetof宏(定义于stddef.h中)

10.作为函数参数的结构:因为C语言的参数传值调用方式要求把参数的一份拷贝传递给函数,所以直接将结构作为参数传递给函数,整个结构会复制到堆栈中,效率会非常低。如果传递给函数的是一个指向结构的指针,指针比整个结构要小的多,所以把它压栈效率会提高很多,当然还可将该指针参数声明为寄存器变量,进一步提高效率,向函数传递指针的缺陷在于函数现在可以对调用程序的结构变量进行修改,如果不希望如此,可以在函数中使用const关键词来防止这类修改

11.位段:位段的声明与结构类似,但它的成员是一个或多个位的字段。struct tag { unsigned (int) member-list : bits ;} ; 注重可移植性的程序应该避免使用位段。使用位段的两个理由:它能够把长度为奇数的数据包装在一起,节省存储空间;可以很方便的访问一个整形值的部分内容,例如寄存器,但可以使用移位和屏蔽来代替。使用位段可以使处理程序更为简单,但有可移植性弱这个缺点。

12.联合:联合的声明与结构类似,但它的行为方式却与结构不同,联合的所有成员引用的是内存中的相同位置。每个成员所引用的位都相同,只是每个成员的类型决定了这些位如何被解释。联合的长度取决于它最长成员的长度。联合变量可以被初始化,但这个初始值必须是联合第一个成员的类型,而且它必须位于一对花括号之内。

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

原创粉丝点击