Other data types

Type aliases (typedef / using)

A type alias is a different name by which a type can be identified. In C++, any valid type can be aliased so that it can be referred to with a different identifier.

In C++, there are two syntaxes for creating such type aliases: The first, inherited from the C language, uses the  typedef keyword:

typedef existing_type new_type_name ;

where  existing_type is any type, either fundamental or compound, and  new_type_name is an identifier with the new name given to the type.

For example:

1
2
3
4
typedef char C;
typedef unsigned int WORD;
typedef char * pChar;
typedef char field [50]; 
 


This defines four type aliases:  CWORDpChar, and  field as  charunsigned intchar* and  char[50], respectively. Once these aliases are defined, they can be used in any declaration just like any other valid type:

1
2
3
4
C mychar, anotherchar, *ptc1;
WORD myword;
pChar ptc2;
field name; 
 


More recently, a second syntax to define type aliases was introduced in the C++ language:

 
using new_type_name = existing_type ;
 


For example, the same type aliases as above could be defined as:

1
2
3
4
using C = char;
using WORD = unsigned int;
using pChar = char *;
using field = char [50]; 
 


Both aliases defined with  typedef and aliases defined with  using are semantically equivalent. The only difference being that typedef has certain limitations in the realm of templates that  using has not. Therefore,  using is more generic, although typedef has a longer history and is probably more common in existing code.

Note that neither  typedef nor  using create new distinct data types. They only create synonyms of existing types. That means that the type of  myword above, declared with type  WORD, can as well be considered of type  unsigned int; it does not really matter, since both are actually referring to the same type.

Type aliases can be used to reduce the length of long or confusing type names, but they are most useful as tools to abstract programs from the underlying types they use. For example, by using an alias of int to refer to a particular kind of parameter instead of using int directly, it allows for the type to be easily replaced by long (or some other type) in a later version, without having to change every instance where it is used.

Unions

Unions allow one portion of memory to be accessed as different data types. Its declaration and use is similar to the one of structures, but its functionality is totally different:


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

This creates a new union type, identified by  type_name, in which all its member elements occupy the same physical space in memory. The size of this type is the one of the largest member element. For example: 

1
2
3
4
5
union mytypes_t {
  char c;
  int i;
  float f;
} mytypes;
 


declares an object ( mytypes) with three members:

1
2
3
mytypes.c
mytypes.i
mytypes.f
 


Each of these members is of a different data type. But since all of them are referring to the same location in memory, the modification of one of the members will affect the value of all of them. It is not possible to store different values in them in a way that each is independent of the others.

One of the uses of a union is to be able to access a value either in its entirety or as an array or structure of smaller elements. For example: 

1
2
3
4
5
6
7
8
union mix_t {
  int l;
  struct {
    short hi;
    short lo;
    } s;
  char c[4];
} mix;
 


If we assume that the system where this program runs has an  int type with a size of 4 bytes, and a  short type of 2 bytes, the union defined above allows the access to the same group of 4 bytes:  mix.lmix.s and  mix.c, and which we can use according to how we want to access these bytes: as if they were a single value of type  int, or as if they were two values of type  short, or as an array of  char elements, respectively. The example mixes types, arrays, and structures in the union to demonstrate different ways to access the data. For a little-endian system, this union could be represented as:

 
The exact alignment and order of the members of a union in memory depends on the system, with the possibility of creating portability issues.

Anonymous unions

When unions are members of a class (or structure), they can be declared with no name. In this case, they become   anonymous unions, and its members are directly accessible from objects by their member names. For example, see the differences between these two structure declarations: 

structure with regular unionstructure with anonymous union
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;

The only difference between the two types is that in the first one, the member union has a name ( price), while in the second it has not. This affects the way to access members  dollars and  yen of an object of this type. For an object of the first type (with a regular union), it would be:

1
2
book1.price.dollars
book1.price.yen
 


whereas for an object of the second type (which has an anonymous union), it would be: 

1
2
book2.dollars
book2.yen
 


Again, remember that because it is a member union (not a member structure), the members  dollars and  yen actually share the same memory location, so they cannot be used to store two different values simultaneously. The  price can be set in  dollars or in  yen, but not in both simultaneously.

Enumerated types (enum)

Enumerated types are types that are defined with a set of custom identifiers, known as  enumerators, as possible values. Objects of these  enumerated types can take any of these enumerators as value.

Their syntax is:


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

This creates the type  type_name, which can take any of  value1value2value3, ... as value. Objects (variables) of this type can directly be instantiated as  object_names.

For example, a new type of variable called  colors_t could be defined to store colors with the following declaration: 

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


Notice that this declaration includes no other type, neither fundamental nor compound, in its definition. To say it another way, somehow, this creates a whole new data type from scratch without basing it on any other existing type. The possible values that variables of this new type  color_t may take are the enumerators listed within braces. For example, once the   colors_t enumerated type is declared, the following expressions will be valid:

1
2
3
4
colors_t mycolor;
 
mycolor = blue;
if (mycolor == green) mycolor = red; 
 


Values of  enumerated types declared with  enum are implicitly convertible to the integer type  int, and vice versa. In fact, the elements of such an  enum are always assigned an integer numerical equivalent internally, of which they become an alias. If it is not specified otherwise, the integer value equivalent to the first possible value is  0, the equivalent to the second is  1, to the third is  2, and so on... Therefore, in the data type  colors_t defined above,  black would be equivalent to   0blue would be equivalent to  1green to  2, and so on...

A specific integer value can be specified for any of the possible values in the enumerated type. And if the constant value that follows it is itself not given its own value, it is automatically assumed to be the same value plus one. For example:

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


In this case, the variable  y2k of the enumerated type  months_t can contain any of the 12 possible values that go from january to  december and that are equivalent to the values between  1 and  12 (not between  0 and  11, since  january has been made equal to  1).

Because enumerated types declared with enum are implicitly convertible to int, and each of the enumerator values is actually of type int, there is no way to distinguish 1 from january - they are the exact same value of the same type. The reasons for this are historical and are inheritance of the C language.

Enumerated types with enum class

But, in C++, it is possible to create real  enum types that are neither implicitly convertible to  int and that neither have enumerator values of type  int, but of the  enum type itself, thus preserving type safety. They are declared with  enum class(or  enum struct) instead of just  enum:

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


Each of the enumerator values of an  enum class type needs to be scoped into its type (this is actually also possible with   enum types, but it is only optional). For example:

1
2
3
4
Colors mycolor;
 
mycolor = Colors::blue;
if (mycolor == Colors::green) mycolor = Colors::red; 
 


Enumerated types declared with  enum class also have more control over their underlying type; it may be any integral data type, such as  charshort or  unsigned int, which essentially serves to determine the size of the type. This is specified by a colon and the underlying type following the enumerated type. For example:

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


Here, Eyecolor is a distinct type with the same size of a char (1 byte).

Reference

http://www.cplusplus.com/doc/tutorial/other_data_types/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值