其他数据类型(Other data types)

重要的事情说三遍:

强烈建议按照目录结构中的顺序学习!!!点我查看教程目录结构

强烈建议按照目录结构中的顺序学习!!!点我查看教程目录结构

强烈建议按照目录结构中的顺序学习!!!点我查看教程目录结构

类型别名(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];

这定义了四个类型别名:CWORDpCharfield 分别为 charunsigned intchar*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 没有。因此,using 更通用,尽管 typedef 历史更悠久,在现有代码中可能更常见。

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

类型别名可以用于减少长或复杂类型名称的长度,但它们最有用的是作为工具来使程序与它们使用的底层类型分离。例如,通过使用 int 的别名来引用特定类型的参数,而不是直接使用 int,可以在以后版本中轻松将类型替换为 long(或其他类型),而无需更改使用该类型的每个实例。

联合(Unions)

联合允许一个内存段以不同的数据类型进行访问。它的声明和使用与结构相似,但功能完全不同:

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;

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

union.jpg

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

匿名联合

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

// 具有常规联合的结构

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),而在第二种类型中则没有。这影响了访问对象成员 dollarsyen 的方式。对于第一种类型的对象(具有常规联合),它是:

book1.price.dollars
book1.price.yen

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

book2.dollars
book2.yen

再次提醒,由于它是成员联合(而不是成员结构),成员 dollarsyen 实际上共享相同的内存位置,因此它们不能同时用于存储两个不同的值。价格可以用 dollarsyen 表示,但不能同时表示两者。

枚举类型(enum)

枚举类型是用一组自定义标识符(称为枚举值)定义的类型作为可能的值。此枚举类型的对象可以取这些枚举值中的任何一个作为值。

其语法为:

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

这创建了类型 type_name,其可以取 value1value2value3 等作为值。可以直接实例化该类型的对象(变量)作为 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 声明的枚举类型的值可以隐式转换为整数类型。实际上,这种 enum 的元素总是被内部赋予一个整数数值等效值,可以隐式转换为该数值。如果未另行指定,第一个可能值的整数值等效于 0,第二个等效于 1,第三个等效于 2,依此类推……因此,在上面定义的 colors_t 数据类型中,black 等效于 0blue 等效于 1green 等效于 2,依此类推……

可以为枚举类型中的任何可能值指定特定的整数值。如果紧随其后的常量值本身没有给出自己的值,则自动假定其值相同加一。例如:

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

在这种情况下,枚举类型 months_t 的变量 y2k 可以包含从 januarydecember 的 12 个可能值中的任何一个,这些值等效于 112 之间的值(而不是 011,因为 january 被等同于 1)。

具有 enum class 的枚举类型

但是,在 C++ 中,可以创建真正的 enum 类型,这些类型既不能隐式转换为 int,也不能具有 int 类型的枚举值,而是具有枚举类型本身的值,从而保留类型安全性。它们用 enum class(或 enum struct)而不是 enum 声明:

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

enum class 类型的每个枚举值需要在其类型内进行作用域限定(这实际上对于 enum 类型也是可能的,但仅仅是可选的)。例如:

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

enum class 声明的枚举类型还可以更好地控制其底层类型;它可以是任何整数数据类型,例如 charshortunsigned int,这实际上用于确定类型的大小。这是通过在枚举类型之后加上冒号和底层类型来指定的。例如:

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

这里,EyeColor 是一个具有 char(1 字节)大小的独特类型。

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值