C++内置的基本数据类型可以分为整数类型和浮点数类型。当然在基本类型的基础上还可以创建复合类型,如数组、字符串、指针和结构(这里不做讨论)。
常见的整型有10种:short,int,long,long long,unsigned short,unsigned int,unsigned long,unsigned long long,char,bool
常见的浮点类型有3种:float,double,long double
在对这些不同的类型进行运算时,C++会自动执行相应的类型转换:
- 将一种类型的值赋给另一种类型的变量时,C++将对值进行类型转换
- 表达式中包含不同的类型时,C++将对值进行类型转换
- 将参数传递给函数时,C++将对值进行类型转换
1. 初始化和赋值进行的转换
C++允许将一种类型的值赋给另一种类型的变量。这样做时,值将被转换为接收变量的类型。
将一个值赋给取值范围更大的类型通常不会导致什么问题,只是占用的字节更多而已。然而如果将一个大范围类型的值赋给小范围类型的变量时,有可能会出现一些转换问题:
- 将较大的浮点类型转换为较小的浮点类型,如将double转换为float。精度(有效数位)会降低,而且值有可能会超过目标类型的取值范围,在这种情况下结果将是不确定的。
- 将浮点型转换为整型,如将float转换为int。数字会被截短(除掉小数部分),而且原来的值有可能超过目标类型的取值范围,在这种情况下结果将是不确定的。
- 将较大的整型转换为较小的整型,如将long转换为short。原来的值有可能超过目标类型的取值范围,通常只复制右边的字节。
- 将0赋给bool变量时,将被转换为false;而非0值将被转换为true。
传统的初始化行为与赋值相同。
2. 以{ }方式初始化时进行的转换
C++使用列表初始化时,它对类型转换的要求更严格。具体来说,==列表初始化不允许缩窄(narrowing),它要求目标变量必须能够存下赋给它的值。==因此列表初始化不允许将浮点型转换为整型。在不同整型之间的转换或将整型转换为浮点型可能被允许,条件是编译器知道目标变量足够存储赋给它的值。
例如,可将long变量初始化为int值,因为long总是至少与int一样长;相反方向的转换也可能被允许,只要int变量能够存储赋给它的long常量。
3.表达式中的转换
当同一个表达式中包含两种不同的算术类型时,C++将执行两种自动转换:首先,一些类型在出现时便会自动转换;其次,有些类型在与其他类型同时出现在表达式中时将被转换。
- 在计算表达式时,C++ 将bool、char和 short值转换为int,这些转换被称为整型提升(integral promotion)。通常int类型是计算机最自然的类型,这意味着及计算机使用这种类型时,运算速度最快。
例如:
short chickens = 20;
short ducks = 35;
short fow1 = chickens + ducks; //C++程序取得chickens和ducks的值,并将它们转换为int
//然后,程序再将结果转换为short类型
- 当运算涉及两种类型时,较小的类型将被转换为较大的类型。
例如:程序计算表达式 9.0 / 5 ,由于9.0的类型为double,因此程序在用5除之前将5转换为double类型。
4. 传递参数时的转换
传递参数时的类型转换通常由函数原型控制,转换规则与赋值情况类似。
5. 强制类型转换
C++还允许通过强制类型转换机制显式的进行类型转换。强制类型转换的通用格式有两种,如下:
(typeName) value
typeName (value) //converts value to typeName type
强制类型转换不会修改变量本身,而是创建一个新的、指定类型的值,可以在表达式中使用这个值。
C++还引入了4个强制类型转换运算符,他们比传统强制类型转换更严格。在这四个运算符中,static_cast<>运算符可用于将值从一种数值类型转换为另一种数值类型。如下:
static_cast<typeName> (value) //converts value to typeName type
参考文献:
《C++ Primer Plus》(第6版)