在变量一章中,我们查看了原始数据类型。但是,高级数据类型使我们可以更灵活地管理程序中的数据。
结构
结构是由其他数据类型的变量(可能包括其他结构)组成的数据类型。它们用于将信息片段分组为有意义的单元,并且还允许一些其他方式无法实现的构造。在结构中声明的变量称为“成员”。一个使用struct
关键字定义结构。例如:
struct mystruct { int int_member ; 双倍 成员; char string_member [ 25 ]; } struct_var ;
struct_var
是一个类型的变量struct mystruct
,我们与新struct mystruct
数据类型的定义一起声明。更常见的是,struct变量是在结构定义之后声明的,使用以下形式:
struct mystruct struct_var ;
通常的做法是创建一个类型同义词,这样我们就不必一直输入“struct mystruct”。C允许我们使用typedef
语句来实现这一点,该语句将类型别名:
typedef struct { // ... } Mystruct ;
它struct
本身是一个不完整的类型(由于第一行没有名称),但它是别名的Mystruct
。然后可以使用以下内容:
Mystruct struct_var ;
如果struct变量是指针,则可以使用成员访问运算符.
(点)或间接成员访问运算符->
(箭头)访问struct变量的成员:
struct_var 。int_member = 0 ; struct_var - > int_number = 0 ; //此语句相当于:* struct_var.int_number = 0;
结构不仅可以包含其他结构的变量,还可以包含它们自己的变量。这允许递归定义,当与指针一起使用时非常强大:
struct restaurant_order { char description [ 100 ]; 双倍 价格; struct restaurant_order * next_order ; };
这是链表数据结构的实现。每个节点(餐馆订单)指向另一个节点。链接列表终止在其next_order
变量将被分配给的最后一个节点(在我们的示例中,这将是最后一个顺序)NULL
。
使用时,递归结构定义可能很棘手typedef
。通过使用别名定义,无法在其自己的类型中声明结构变量,因为在计算语句typedef
之前,别名定义不存在typedef
:
typedef struct Mystruct { // ... struct Mystruct * pointer ; // Mystruct *指针; 会导致编译时错误 } Mystruct ;
结构类型的大小等于其所有成员的大小总和。
工会
union的定义类似于struct的定义。两者之间的区别在于,在结构中,成员占用不同的内存区域,但在联合中,成员占用相同的内存区域。因此,在以下类型中,例如:
联合 { int i ; 双 d ; } ü ;
程序员可以访问任何u.i
或u.d
,但不能同时在同一时间。由于u.i
并u.d
占据相同的内存区域,修改一个区域会修改另一个区域的值,有时会以不可预测的方式修改。
联合的大小是其最大成员的大小。
枚举
枚举是表示标签和整数之间关联的人工数据类型。与结构或联合不同,它们不是由其他数据类型组成。一个示例声明:
枚举 颜色 { 红色, 橙色, 黄色, 绿色, 青色, 蓝色, 紫色, } crayon_color ;
在上面的示例中,红色等于0,橙色等于1,…因此每个后续标签比前一个标签大1。可以为整数范围内的标签指定值,但它们必须是文字。
适用于结构和联合的类似声明语法也适用于枚举。此外,通常不需要关注标签所代表的整数:
enum weather weather_outside = rain ;
这种独特的属性使得枚举在switch-case语句中特别方便:
enum weather { 晴天, 多风, 多云, 下雨, } weather_outside ; // ... switch (weather_outside ) { case sunny : wear_sunglasses (); 打破; case windy : wear_windbreaker (); 打破; case cloudy : get_umbrella (); 打破; case rain : get_umbrella (); wear_raincoat (); 打破; }
猜你想读:《C编程.中级C》2.指针与数组的关系