第4章 数据类型及运算符(4)

4.4 类型转换

C++自动执行的类型转换:

1、将一种算术类型的值赋给另一种算术类型的变量时,C++将对值进行转换

2、表达式中包含不同的类型时,C++将对值进行转换

3、将参数传递给函数时,C++将对值进行转换

4.4.1 初始化和赋值进行的转换

C++允许将一种类型的值赋给另一种类型的变量。这样做时,值将被转换为接收变量的类型。

例:

int a = 10;

long b = a ;

将一个值赋给值取值范围更大的类型通常不会导致什么问题。反之则有可能会带来麻烦,如下表所示:

转换

潜在问题

将较大的浮点类型转换为较小的浮点类型,如将double转换为float

精度(有效位数)降低,值可能超出目标类型的取值范围,在这种情况下,结果将是不确定的

将浮点类型转换为整型

小数部分丢失,原来的值可能超出目标类型的取值范围,在这种情况下,结果将是不确定的

将较大的整型转换为较小的整型,如将long转换为short

原来的值可能超出目标类型的取值范围,通常只复制右边的字节

将0赋给bool类型的变量时,将被转换为false;而非零值将被转换为true。

将浮点值赋给整型将导致两个问题。首先,将浮点值转换为整型会将数字截短(除掉小数部分)。其次,float值对于int变量来说可能太大了。

传统初始化的行为与赋值相同。

4.4.2 以{}方式初始化时进行的转换

C++11将使用大括号的初始化称为列表初始化(list-initialization) ,因为这种初始化常用于给复杂的数据类型提供值列表。它对类型转换的要求更严格。具体地说,列表初始化不允许缩窄(narrowing) ,即变量的类型可能无法表示赋给它的值。例如,不允许将浮点型转换为整型。在不同的整型之间转换或将整型转换为浮点型可能被允许,条件是编译器知道目标变量能够正确地存储赋给它的值。例如,可将long变量初始化为int值,因为long总是至少与ing一样长;相反方向的转换也可能被允许,只要int变能够存储赋给它的long常量:

#include <iostream>

int main()
{
	using namespace std;

	cout.setf(ios_base::fixed, ios_base::floatfield);
	float a = 3.12f;
	int b = a; 
	int c(20);
	cout << "a = " << a << " b = " << b << "  c = "<<c<< endl;

	cout << endl;
	const int code = 66;
	int x = 66;
	//char c1{ 31325 }; // narrowing, not allowed
	char c2 = { 66 }; // allowed because char can hold 66
	char c3{ code };// ditto
	//char c4 = { x };//x的值为66,但在编译器看来,x是一个变量,其值可能很大。

	x = 31325;
	char c5 = x;	// allowed by this form of initialization

	return 0;
}

4.4.3 表达式中的转换 ☆

自动转换:

C++执行两种自动转换:首先,一些类型在出现时便会自动转换;其次,有些类型在其他类型同时出现在表达式中时将被转换。

整型提升:

C++将bool、char、unsigned char、signed char和short值转换为int。具体地说,true转换为1,false转换为0。这些转换被称为整型提升。

C++11版本的校验表, 编译器将依次查阅该列表。

(1)如果有一个操作数的类型是long double,则将另一个操作数转换为long double

(2)否则,如果有一个操作数的类型是double,则将另一个操作数转换为double

(3)否则,如果有一个操作数的类型是float,则将另一个操作数转换为float

(4)否则,说明操作数都是整型,因此执行整型提升。

(5)在这种情况下,如果两个操作数都是有符号或无符号的,且其中一个操作数的级别此另一个低,则转换为级别高的类型。

(6)如果一个操作数为有符号的,另一个操作数为无符号的,且无符号操作数的级别比有符号操作数高,则将有符号操作数转换为无符号操作数所属的类型。

(7)否则,如果有符号类型可表示无符号类型的所有可能取值,则将无符号操作数转换为有符号操作数所属的类型。

(8)否则,将两个操作数都转换为有符号类型的无符号版本。

整型级别的转换:

有符号整型按级别从高到低依次为long long、long、int、short和signed char。无符号整型的排列顺序与有符号整型相同。类型char、 signed char和unsigned char的级别相同。类型bool的级别最低。wchar_t、char16_t和char32_t的级别与其底层类型相同。

4.4.4 传递参数时的转换

传递参数时的类型转换通常由C++函数原型控制。如果取消原型对参数传递的控制,C++将对char和short类型(signed和unsigned)应用整型提升。另外,为保持与传统C语言中大量代码的兼容性,在将参数传递给取消原型对参数传递控制的函数时,C++将float参数提升为double。

4.4.5 强制类型转换

C++允许通过强制类型转机制显式地进行类型转换。

强制类型转换的格式有两种:

(1) (typeName) value //来自C语言

(2) typeName (value) //C++,想法是,要让强制类型转换就像是函数调用。

强制类型转换不会修改value变量本身,而是创建一个新的、指定类型的值,可以在表达式中使用这个值。

4.4.6 auto声明

C++11新增了一个工具,让编译器能够根据初始值的类型推断变量的类型。

auto n = 100;

auto x = 1.5;

auto y = 1.3e12L;

习题:

auto fract = 8.25f / 2.5 ;问fract是什么类型?

答案:double。

在默认情况下,像8.242.4E8这样的浮点常量都属于double类型。如果希望常量为float类型,要使用f或F后缀。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值