数据类型转换[C++]

C++丰富的基本类型允许根据需求选择不同的基本类型:11种整型和3种浮点型。在处理大量不同情况,尤其是对不同类型进行运算时,存在潜在的混乱。因此,C++支持自动执行很多类型转换:

  • 将一种算数类型的值赋给另一种算数类型的变量时,C++将对值进行转换。
  • 表达式中包含不同的类型时,C++将对值进行转换。
  • 将参数传递给函数时,C++将对值进行转换。

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

赋值后值将被转换为接收变量的类型。

有些转换是相对安全的:

  • 将一个值赋给取值范围更大的类型通常不会导致什么问题,如short值赋给long变量,只是可能占用更多字节而已。
  • 将零赋给bool变量时会转换成false,将非零值赋给bool变量时会转换成true。

还有些转换则会带来麻烦:

  • 但将一个很大的long值赋给float变量时将降低精度,因为float只有6位有效数字。
  • 将大浮点类型转换为较小的浮点类型,如double值转换为float,会降低精度甚至超出目标类型的取值范围,结果不确定。
  • 将浮点型转换为整型,将会导致小数部分消失(截短),甚至超出目标取值范围,结果不确定(不同系统不一样)。
  • 将较大的整型转换为较小的整型,可能会超出目标类型的取值范围,通常只复制右边的字节。

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

C++11使用大括号{}初始化(即列表初始化)时对类型转换要求更严格。

  • 列表初始化不允许缩窄,即变量的类型可能无法表示赋给它的值,如不允许将浮点型转换为整型。
  • 在不同整型之间转换或将整型转换为浮点型可能被允许,条件是编译器知道目标变量能够正确地存储赋给它的值。

2 表达式中的转换

当同一个表达式中包含两种不同的算数类型时,有以下情况:

  • 一些类型在出现时自动转换:在计算表达式时,C++将bool、char、unsigned char、signed char和short值转换为int,即整型提升,再将计算结果转换为接收变量类型赋给该变量。(int类型为计算最自然的类型,运算速度可能最快。)
  • 还有一些其他整型提升:若short比int短,则unsigned short类型将被转换为int;若两种类型长度相同,则unsigned short类型将被转换为unsigned int。由此确保在对unsigned short进行提升时不会损失数据。
  • 同样,wchar_t被提升成为int、unsigned int、long和unsigned long中第一个宽度足够存储wchar_t取值范围的类型。
  • 还有些类型在与其他类型同时出现时将被转换:不同类型进行运算时,较小类型会转化为较大类型。

C++11版本的编译器校验表顺序:long double,double,float,整型提升。整型提升满足:

  • 有符号整型级别:long long、long、int、short和signed char。无符号整级别与有符号相同。类型char、unsigned char和signed char的级别相同。wchar_t、char16_t和char32_t的级别与其底层类型相同。
  • 如果两个操作数都是有符号的或无符号的,低级别的类型转换为高级别的。
  • 如果一个有符号,一个无符号且级别高,则将有符号的操作数类型转换为无符号操作数所属类型;如果有符号类型的能表示无符号类型的所有取值,则无符号的操作数类型转换为有符号操作数所属类型;否则,将两个操作数都转换为有符号类型的无符号版本。

3 传递参数时的类型转换

传递参数时的类型转换通常由C++函数原型控制。

  • 可以取消原型对参数转换的控制,但这样作并不明智。
  • C++对char和short类型(signed和unsigned)应用整型提升。
  • 为保证与传统C的兼容性,在将参数传递给取消原型对应参数传递控制的函数时, C++将float参数提升为double。

4 强制类型转换

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

int haha = 1;
long haha1 = (long)haha; //来自C语言
long haha2 = long(haha); //纯粹的C++
static_cast<long> haha; //haha编程long类型

强制类型转换并不会改变haha变量本身,而是创建一个新的制定类型的值,可以在表达式中使用这个值。C++新格式使强制类型转换就像是函数调用。

C++还引入4个强制类型转换运算符。

  • static_cast<>可用于将变量本身的值从一种类型转换为另一种类型。
  • dynamic_cast<>
  • const_cast<>
  • reinterpret_cast<>

使用强制转换的原因:

  • 可能有一些值被默认存为double类型,但要使用它们计算得到一个int类型的值。将两个double值求和再前值转换为int类型,与将两者先强制转换成int类型再求和得到的结果很可能是不同的。
  • 使用一种格式的数据能满足不同的期望。

5 C++11的auto声明

auto让编译器能够根据初始值的类型推断变量的类型。

  • auto本是一个C语言关键字,但很少使用。
  • 在初始化声明中若使用auto而不指定变量类型,编译器吧变量的类型设置成与初始值相同。(容易误入歧途)
auto n = 100; //int
auto x = 1.5; //double
auto y = 1.3e12L; //long double
auto z = n; //int

处理复杂类型,如标准模块库(STL)中的类型时,这种自动类型推断便很有意义。

std::vector<double> scores;
std::vector<double>::iterator pv = scores.begin();
//第二句还可以表达为
auto pv = scores.begin();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

贫道绝缘子

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值