C 语言复习与提高---VII. 结构体与共用体

来源:互联网 发布:超声波驱蚊器软件 编辑:程序博客网 时间:2024/05/16 18:16
VII. 结构体与共用体

在程序设计中,常需要把相关数据作为一个整体来处理,其方法是构造新的数据类型。

一、结构体(Structure):聚合数据类型,提供一种把相关数据组合到一起的手段。

1、通常,结构中的成员都是逻辑的。

2、在商业软件中,成员变量名一般习惯以下划线(_)开头。结构变量在被定义后,编译器在编译时为所有成员分配内存。

3、结构体赋值:可以把一个结构变量的全部内容赋值给另一个同类的结构变量,而不必逐个成员的赋值。 注意与数组的区别:数组是不能彼此赋值的,是因为数组名是一个常量指针。数组是一个数据类型的聚集,它本质上不是数据类型。 [例]struct { void main() { int _name; char a[10], b[10]; int _age; a=b; /* ERROR!*/ }perso1, perso2; }

perso1._age=10; perso2=perso1; /* OK */

4、向函数传递结构时,实际上是传递结构成员的值,即都是值传递方式,包括用结构体变量作函数参数及函数返回一结构体变量两种情况。 [注意]与数组的区别:结构体变量名仅代表值,而非地址。

除简单结构外,向函数传递全部结构的方法存在重大缺陷:当执行函数调用时,数据压栈需要开销。这对于多成员结构或成员中有数组的结构,运行性能严重恶化。解决方案是:向结构传递指针。

向函数传递结构指针时,压栈的仅仅是指针本身,这使得函数调用非常快。在某些情况下的另一个优点是,函数可以修改作为变量的结构的内容。

5、成员结构:结构体中的结构。C89 规定,结构体至少应允许嵌套 15 层,C99 增加至 63 层。

6、结构体的应用:结构体经常被应用于动态数据结构。在 C 语言中由结构体类型和动态存储分配函数来实现动态数据结构。

由于数组这样的静态数据结构在被定义后,系统将在内存中为其分配连续的内存空间,且在程序运行期间保持不变(或整体被撤消),因此虽然它有可以随机访问每一个数组元素的优点,但是它有更严重的缺陷:在对元素进行插入和删除运算时,需要移动大量元素而可能降低效率。并且,由于数组大小固定,存储在连续的内存空间中,在数据量变化较大的情况下,必须按最大需要进行分配,有可能浪费很多内存。另外,在程序运行期间无法根据需要对数组进行扩充,也不可能释放其中的某一部分内存。

在实际工作中,有很多问题需要用到动态方式的数据结构,它们占用的空间可以动态变化(可以根据需要随机地分配和释放内存)。在逻辑上连续的元素,在内存中却不一定连续。

具体实例:单向链表,二*树等。(不再详细赘述)

7、在把 C++ 代码移植到 C 时,需要注意: struct str { int _x; int _y; };

struct str objet; /* 在 C 语言中必须有 struct,否则编译器报错。C++ 也可使用 */ str objet; /* C++ 的格式 */

在 C++ 中,结构体名是完整的类型名,可以被自身使用以定义变量。

二、共用体(Union):允许多个不同的变量(可以是相同类型或不同类型)共用同一块内存空间,提供了以多种方式解释同一位模式的方法。

1、声明共用体时,编译器为其分配一块内存,大小为其成员变量中最大的变量所占用的字节数。

2、共用体常用于需要频繁进行类型转换的场合,因为程序可以使用共用体中的数据。

三、位段(bit-field):访问字节中的位的内设机制,可以访问单个位。这是 C 语言中访问二进制位的两种方式中的一种(另一种方式是位运算)。

1、特点: - 内存紧张时,可把若干 BOOL 变量存入一个字节。 - 某些设备把编码信息传送到各个位。 - 某些加密算法需要访问字节中的位。

2、相对于位操作来说,位段能够增加更多的代码结构,可以提高效率。

3、C 语言的位段由结构体实现,每个位段是位段结构体中的成员,以位为单位来定义长度。

4、与普通结构体相比,位段的使用也有一定的限制和细节问题,如:不能取其地址,位段变量不能跨越数组边界,位段只能被声明为 int 或 unsigned int 类型等。另外,不同的机器对位段的成员的存储顺序是不一样的,这意味着使用位段变量就引入了对机器的依赖。

四、枚举(enum):被命名的整型常量的列表。

1、每一个符号代表一个整数值。

2、第一个符号的值是零。

3、每一个符号的值都是其前导者的值加一。

4、枚举表中的名字不是字符串。 [错例]enum color { black, white, blue, red=4, magenta, brown, gray=20, yellow }; enum color c1; /* 定义变量 c1 为 color 类型*/ c1=gray; printf("%s/n", c1); /* ERROR!*/ /* gray 只是一个整型数值的名字,而非字符串。*/

要把枚举型翻译成字符串只能靠编程实现,如使用一个串数组,用枚举值作数组下标,或者使用 switch() 控制结构。因此,枚举常用于不产生这种转换的程序中(如定义编译器的符号表)。

 
原创粉丝点击