Home C&C++函数库 c++ 语法 程序源码 Linux C库

其它数据类型

☞ 类型别名(typedef / using)



类型别名是可用于标识类型的不同名称。在c++中,任何有效类型都可以有别名,这样就可以用不同的标识符引用它。 在c++中,创建这种类型别名有两种语法:第一种,继承自C语言,使用typedef关键字:

typedef existing_type new_type_name ;

existing_type是任何类型,可以是基本类型,也可以是复合类型,new_type_name是赋予该类型新名称的标识符。

例如:

typedef char C;
typedef unsigned int WORD;
typedef char * pChar;
typedef char field [50];

这定义了四个类型别名:C、WORD、pChar和field分别为char、unsigned int、char*和char[50]。 一旦这些别名被定义,它们就可以像其他有效类型一样在任何声明中使用:

C mychar, anotherchar, *ptc1;
WORD myword;
pChar ptc2;
field name;

最近,c++语言中引入了第二种定义类型别名的语法:

using new_type_name = existing_type ;

例如,上述类型别名可以定义为:

using C = char;
using WORD = unsigned int;
using pChar = char *;
using field = char [50];

typedef定义的别名和using定义的别名在语义上是等价的。 唯一的区别是,typedef在模板领域有一定的限制,而using没有。 因此,虽然typedef的历史更长,并且可能在现有代码中更常见,但是using更通用。

注意,无论是typedef还是using都不能创建新的不同的数据类型。它们只创建现有类型的同义词。 这意味着上面用WORD类型声明的myword类型也可以被认为是unsigned int类型;这并不重要, 因为它们实际上指的是同一种类型。

类型别名可用于减少冗长或令人困惑的类型名的长度,但它们最有用的是作为工具, 从它们使用的底层类型中抽象程序。例如,通过使用int的别名来引用特定类型的形参, 而不是直接使用int,它允许该类型在以后的版本中很容易被long(或其他一些类型)替换, 而不必更改使用它的每个实例。

☞ 联合



联合允许将内存的一部分作为不同的数据类型访问。它的声明和使用类似于结构体,但功能完全不同:

union type_name {
  member_type1 member_name1;
  member_type2 member_name2;
  member_type3 member_name3;
  .
  .
} object_names;

这将创建一个新的联合类型,由type_name标识,其所有成员元素在内存中占据相同的物理空间。 该类型的大小由最大的成员元素决定。例如:

union mytypes_t {
  char c;
  int i;
  float f;
} mytypes;

声明一个带有三个成员的对象(mytypes):

mytypes.c
mytypes.i
mytypes.f

每个成员都属于不同的数据类型。但由于它们在内存中的相同位置, 因此修改其中一个成员将影响所有成员的值。在它们中存储不同的值是不可能的, 每个值都是独立于其他值的。

联合的用途之一是能够访问值的整体,或作为数组或较小元素的结构。例如:

union mix_t {
  int l;
  struct {
    short hi;
    short lo;
    } s;
  char c[4];
} mix;

如果我们假设这个程序运行的系统有一个大小为4字节的int类型和一个长度为2字节的short类型, 那么上面定义的联合允许访问相同的4字节组: mix.l, mix.s 和 mix.c, 可以根据访问这些字节的方式使用它们:就像它们是一个int类型的单一值, 或就像它们是两个short类型的值,或分别作为一个char元素的数组。 该示例在联合中混合了类型、数组和结构,以演示访问数据的不同方式。对于小端系统,这个联合可以表示为:

内存中联合成员的精确对齐和顺序取决于系统,可能会产生可移植性问题。

☞ 匿名联合



当联合是类(或结构体)的成员时,可以不带名称地声明它们。 在本例中,它们成为匿名联合,其成员可以通过成员名直接从对象访问。 例如,请看这两种结构声明之间的区别:

结构体内常规联合 结构体内匿名联合
struct book1_t {
  char title[50];
  char author[50];
  union {
    float dollars;
    int yen;
  } price;
} book1;
struct book2_t {
  char title[50];
  char author[50];
  union {
    float dollars;
    int yen;
  };
} book2;

这两种类型之间的唯一区别是,在第一种类型中,成员联合有名称(price),而在第二种类型中没有。 这将影响访问该类型对象的成员dollers和yen的方式。对于第一种类型的对象(成员是常规联合),它将是:

book1.price.dollars
book1.price.yen

而对于第二种类型的对象(成员是匿名联合),它将是:

book2.dollars
book2.yen

同样,请记住,因为它是一个成员联盟(而不是成员结构),成员dollers和yen实际上共享同一个内存位置, 所以它们不能被用来同时存储两个不同的值。price 可以用dollers或yen确定,但不能同时用两种货币。

☞ 枚举类型(枚举)



枚举类型是使用一组自定义标识符定义的类型,被称为枚举成员,作为可能的值。 这些枚举类型的对象可以将这些枚举中的任何一个枚举成员作为值。

他们的语法是:

enum type_name {
  value1,
  value2,
  value3,
  .
  .
} object_names;

这将创建type_name类型,它可以接受value1, value2, value3,…作为值。 这种类型的对象(变量)可以直接实例化为object_names。

例如,可以定义一个名为colors_t的新类型变量来存储颜色,声明如下:

enum colors_t {black, blue, green, cyan, red, purple, yellow, white};

注意,该声明在其定义中不包括其他类型,既不包括基本类型也不包括复合类型。 换句话说,这将从头创建一个全新的数据类型,而不基于任何其他现有类型。 新类型color_t的变量可能接受的值是花括号中列出的枚举成员。 例如,一旦声明了colors_t枚举类型,以下表达式将有效:

colors_t mycolor;

mycolor = blue;
if (mycolor == green) mycolor = red;

用enum声明的枚举类型的值可以隐式转换为整数类型。 实际上,这种枚举的元素总是在内部分配一个等价的整数数值,它们可以隐式转换为这个数值. 如果没有指定,则与第一个可能值相等的整数值为0,与第二个相等的整数值为1,第三个为2, 依此类推… 因此,在上面定义的数据类型colors_t中,黑色等于0,蓝色等于1,绿色等于2,等等……

可以为枚举类型中的任何值指定特定的整数值。 如果它后面的成员本身没有给出它自己的值,它会自动地被假定为相同的值加1。例如:

enum months_t { january=1, february, march, april,
                may, june, july, august,
                september, october, november, december} y2k;

在本例中,枚举类型months_t的变量y2k可以是从1月到12月的12个可能值中的任何一个, 这些值等价于1到12之间的值(不是0到11之间的值,因为1月被设为1)。

☞ 枚举类型与枚举类



但是,在c++中,可以创建既不能隐式转换为int类型的实际枚举类型,也没有int类型的枚举值, 而是枚举类型本身的枚举值,从而保持类型安全。它们是用enum类(或enum结构体)声明的,而不是用enum:

enum class Colors {black, blue, green, cyan, red, purple, yellow, white};

枚举类类型的每个枚举值都需要限定在其类型中(实际上对于枚举类型也可以这样做,但它只是可选的)。例如:

Colors mycolor;

mycolor = Colors::blue;
if (mycolor == Colors::green) mycolor = Colors::red;

用enum类声明的枚举类型对其基础类型也有更多的控制;它可以是任何整型数据类型, 如char、short或unsigned int,其本质上用于确定类型的大小。这是由冒号和枚举类型之后的基础类型指定的。例如:

enum class EyeColor : char {blue, green, brown};

这里,Eyecolor是一种不同的类型,具有相同的char(1字节)大小。



联系我们 免责声明 关于CandCplus 网站地图