联合
union与struct最主要的区别在于存储值的区别,我们下面会简要介绍。
联合的创建
联合(union) 是一种数据类型,它能在同一个内存空间中储存不同的数据类型(不是同时储存)。其典型的用法是,设计一种表以储存既无规律、事先也不知道顺序的混合类型。使用联合类型的数组,其中的
联合都大小相等,每个联合可以储存各种数据类型。创建联合和创建结构的方式相同,需要一个联合模板和联合变量。可以用一个步骤定义联合,也可以用联合标记分两步定义。下 面是一个带标记的联合模板:
union hold {
int digit;
double bigfl;
char letter;
};
根据以上形式声明的结构可以储存一个 int类型、一个double类型和char类型的值。然而,声明的联合只能储存一个 int类型的值或一个double类型的值或char类型的值。可以初始化联合。需要注意的是,联合只能储存一个值,这与结构不同。
使用联合
下面是联合的一些用法:
union hold fit; //创建hold类型的联合变量
fit.digit = 23;//把23储存在fit,占2字节
fit.bigfl = 2.0; // 清除23.储存2.0,占8字节
fit.letter=‘h’; //清除2.0,储存h,占1字节
点运算符表示正在使用哪种数据类型。在联合中,一次只储存一个值。即使有足够的空间,也不能同时储存一个char类型值和一个int类型值。编写代码时要注意当前储存在联合中的数据类型。
和用指针访问结构使用->运算符一样,用指针访问联合时也要使用->运算符(这里不懂指针访问结构的可以看我的上个文章:结构指针的使用):
pu = &fit;
x = pu->digit; //相当于x=fit.digit
不要像下面的语句序列这样:
fit.letter = ‘A’;
flnum = 3.02*fit.bigfl; //错误
以上语句序列是错误的,因为储存在fit中的是char类型,但是下一行却假定fit中的内容是double类型。
枚举类型
枚举类型的创建
可以用枚举类型(emumerated type)声明符号名称来表示整型常量。使用enum关键字,可以创建一个新“类型”并指定它可具有的值(实际上,enum 常量是int类型,因此,只要能使用int类型的地方就可以使用枚举类型)。枚举类型的目的是提高程序的可读性。它的语法与结构的语法相同。例如,可以这样声明:
enum spectrum {red, orange, yel1ow, green, blue, violet};
enum spectrum color;
第1个声明创建了spetrum作为标记名,允许把enum spetrum 作为一个类型名使用。第2个声明使color作为该类型的变量。第1个声明中花括号内的标识符枚举了spectrum变量可能有的值。因此,color可能的值是red、orange. yellow 等。这些符号常量被称为枚举符(enumerator)。 然后,便可这样用:
int c;
color = blue;
if (color == yellow)
for (color = red; color <= violet; color++)
枚举默认值
默认情况下,枚举列表中的常量都被赋予0、1、2等。因此,下面的声明中nina的值是3:
enum kids {nippy, slats, skippy, nina, liz};
赋值
在枚举声明中,可以为枚举常量指定整数值:
enum levels {low = 100, medium = 500, high = 2000};
如果只给一个枚举常量赋值,没有对后面的枚举常量赋值,那么后面的常量会被赋予后续的值。例如,
假没有如下的声明:
enum feline {cat, lynx = 10, puma, tiger};
那么,cat的值是0 (默认),lynx、 puma 和tiger的值分别是10、11、12。
typedef(重要,常用)
typedef工具是一个高级数据特性,利用typedef可以为某一类型自定义名称。 这方面与#define类似,但是两者有3处不同:
■与#define 不同,typedef 创建的符号名只受限于类型,不能用于值。
■typedef由编译器解释,不是预处理器。
■在其受限范围内, typedef 比#define更灵活。
下面介绍typedef的工作原理。假设要用BYTE表示1字节的数组。只需像定义个char类型变量一样定义BYTE,然后在定义前面加上关键字typedef即可:
typedef unsigned char BYTE;
随后,便可使用BYTE来定义变量:
BYTE x,y[10], * z;
该定义的作用域取决于typedef定义所在的位置。如果定义在函数中,就具有局部作用域,受限于定义所在的函数。如果定义在函数外面,就具有文件作用域。
typedef与#define异同
重点:typedef后面要加分号,#define不用
typedef的一些特性与#define的功能重合。例如:
#define BYTE unsigned char
这使预处理器用BYTE替换unsigned char. 但是也有#define没有的功能:
typedef char * STRING;
没有typedef关键字,编译器将把STRING识别为一个指向char的指针变量。有了typedef 关键字,编译器则把STRING解释成一个类型的标识符,该类型是指向char的指针。因此:
STRING name, sign;
相当于:
char * name, * sign;
但是,如果这样假设:
#define STRING char *
然后,下面的声明:
STRING name, sign;
将被翻译成:
char * name, sign;
这导致只有name才是指针。