C++ Tutorials: C++ Language: Compound data types: Other data types

本文详细介绍了C++中的类型别名,包括typedef和using两种语法,并通过示例说明它们如何创建类型同义词。接着,探讨了联合(union)的概念,展示了如何在同一内存位置存储不同数据类型。最后,讨论了枚举类型,包括传统的枚举和强类型的enum class,以及它们在内存管理和类型安全上的特点。
摘要由CSDN通过智能技术生成

C++官方参考链接:Other data types - C++ Tutorials (cplusplus.com)

其他数据类型
类型别名(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没有。因此,using更加泛型,尽管typedef的历史更悠久,在现有代码中可能更常见。 
注意,无论是typedef还是using都不会创建新的不同的数据类型。它们只创建现有类型的同义词。这意味着上面用WORD类型声明的myword的类型也可以被认为是unsigned int类型;这并不重要,因为两者实际上都引用了相同的类型。
类型别名可以用来减少冗长或令人困惑的类型名的长度,但它们最有用的是作为从它们使用的基础类型抽象程序的工具。例如,通过使用int的别名来引用特定类型的形参,而不是直接使用int,它允许在以后的版本中很容易地用long(或其他类型)替换该类型,而不必更改使用它的每个实例。

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

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

这将创建一个新的联合(union)类型,由type_name标识,其中其所有成员元素在内存中占用相同的物理空间。该类型的大小是最大的成员元素之一。例如:
union mytypes_t {
  char c;
  int i;
  float f;
} mytypes;
声明一个具有三个成员的对象(mytypes):
mytypes.c
mytypes.i
mytypes.f
每个成员都具有不同的数据类型。但是由于它们都指向内存中的同一个位置,修改其中一个成员将影响所有成员的值。不可能将不同的值以彼此独立的方式存储在其中。 
联合(union)的用途之一是能够访问整个值,或者作为较小元素的数组或结构访问值。例如:
union mix_t {
  int l;
  struct {
    short hi;
    short lo;
    } s;
  char c[4];
} mix;
如果我们假设这个程序运行的系统有一个长度为4字节的int类型和一个长度为2字节的short类型,那么上面定义的联合(union)允许访问相同的4字节组:mix.l、mix.s和mix.c,我们可以根据我们想要访问这些字节的方式来使用它们:就像它们是int类型的单个值,或者是short类型的两个值,或者分别作为char元素的数组。该示例在联合(union)中混合了类型、数组和结构,以演示访问数据的不同方式。对于一个小端系统,这个联合(union)可以表示为:

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

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

structure with regular union(具有普通联合的结构)
struct book1_t {
  char title[50];
  char author[50];
  union {
    float dollars;
    int yen;
  } price;
} book1;

structure with anonymous union(具有匿名联合的结构)
struct book2_t {
  char title[50];
  char author[50];
  union {
    float dollars;
    int yen;
  };
} book2;

这两种类型之间的唯一区别是,在第一种类型中,成员联合(union)具有名称(price),而在第二种类型中没有。这将影响访问此类型对象的成员dollars和yen的方式。对于第一种类型的对象(具有普通联合(union)),它将是:
book1.price.dollars
book1.price.yen
而对于第二种类型的对象(具有匿名联合(union)),则为:
book2.dollars
book2.yen 
同样,请记住,因为它是成员联合(union)(而不是成员结构),所以成员dollars和yen实际上共享相同的内存位置,因此它们不能用于同时存储两个不同的值。price可以用dollars或yen设定,但不能同时用两种货币。

枚举类型(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将等价于0、blue将等价于1、green将等价于2、等等…… 可以为枚举类型中的任何可能值指定特定的整数值。如果它后面的常量本身没有给出它自己的值,它就会自动被假设为相同的值加1。例如:
enum months_t { january=1, february, march, april,
                may, june, july, august,
                september, october, november, december} y2k;
在本例中,枚举类型months_t的变量y2k可以包含从january到december的12个可能值中的任何一个,这些值等价于1到12之间的值(不是0到11之间的值,因为january已经被设置为1)。

带有枚举类(enum class)的枚举类型
但是,在C++中,可以创建既不能隐式转换为int的真正enum类型,也没有int类型的枚举成员值,而是enum类型本身,从而保持类型安全。它们用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声明的枚举类型对其基本类型也有更多的控制;它可以是任何整型数据类型,例如char、short或unsigned int,这些数据类型主要用于确定类型的大小。这是由冒号和枚举类型后面的基本类型指定的。例如:
enum class EyeColor : char {blue, green, brown};
在这里,Eyecolor是具有相同大小的char(1字节)的不同类型。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_40186813

你的能量无可限量。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值