C++类型转换

前言

  • 1)当我们给无符号类型的变量赋值一个超出表示它表示范围的值时,结果是初始值对范围总数取模后的余数。如下图,unsigned
    short为2,占两个字节,则范围为0~65535。所以-1取模(-1+65536)后值就为65535
std::cout << sizeof(unsigned short) << std::endl;
unsigned short i = -1;
std::cout << i << std::endl;

在这里插入图片描述

  • 2)当我们赋给带符号类型一个超出它范围的值时,结果是未定义的(undefined)。此时,程序可能会继续工作、可能崩溃,也可能生成垃圾数据。(见C++
    primer第5版2.1.2 P33)
    在这里插入图片描述

隐式转换

先看下面的式子有几次隐式的类型转换?
在这里插入图片描述
答案是两次。
第一次发生在相加的运算中。C++不会直接将两个不同的类型的值相加,并且算术类型之间的隐式转换被设计的尽可能避免损失精度。(C++ primer 第5版 4.11 P141)。所以整型会被转为double形:3->3.0,然后和3.541加。
第二次发生在初始化阶段。因为变量的类型已经固定,所以初始化的值被转换为变量的类型。既6.541->6给ival。

何时发生隐式类型转换(C++ primer 第5版 4.11 P141)

在这里插入图片描述

算术转换

含义:将一种算术类型转换为另一种算术类型。如前面的所述的3+3.541转换为3.0+3.541。

整型提升:

含义是将小的整型提升为大的整型。既char、short、unsigned short、bool、signed char、unsigned char等较小的数据类型会转换为int型。但是注意,这种提升的前提是小数据类型的范围在int范围类型内。一旦不在范围内,则提升为unsigned int。比如在某些系统中unsigned short和int占同样的字节,此时, unsigned short就转换为unsigned int,而不是int。

下面介绍算数类型转换的规则:

  1. 首先按“整型提升”规则,将小于int型的整型提升为int型。
  2. “整型提升”之后的两个对象都是无符号或者都是带符号。同类型则直接计算,否则小类型转换为大类型。
char cval;
short sval; 
int ival; 
long lval;

定义了以上的变量,则
计算cval+sval:先把两个都提升为int型,为同类型,计算;
计算sval+ival:先把sval提升为int型,为同类型,计算;
计算cval+lval:将cval提升为int型,int和long都为带符号但不同类型。则小转大,int转换为long型后再计算。

  1. “整型提升”之后,两个对象一个无符号一个有符号,此类情况较复杂,需分类讨论:

情况1:若无符号的不小于带符号的,将有符号的转换为无符号的,示意图如下:
在这里插入图片描述

std::cout <<"sizeof(int) = "<< sizeof(int) << std::endl;
std::cout << "sizeof(long long) = " << sizeof(long long) << std::endl;
	
unsigned int ui = 10; //无符号的大小为4
unsigned long long l = 50; //无符号的大小为8
int i = -42; //带符号的大小为4

std::cout << "typeid(unsigned long long).name():" << typeid(unsigned long long).name() << std::endl;
std::cout << "typeid(i + ui).name():"<<typeid(i + ui).name() << std::endl;
std::cout << "typeid(i + l).name():" << typeid(i + l).name() << std::endl;

在这里插入图片描述

从上面的例子可以看到:unsigned int 和int做计算时,转换为unsigned int计算。unsigned long long 和 int 做计算时,转换为unsigned long long计算。

情况2:若带符号大于无符号的,此时分情况讨论:

  • i.若无符号的都在有符号的范围内,则无符号的转为有符号的,示意图如下:
    在这里插入图片描述
std::cout <<"sizeof(int) = "<< sizeof(int) << std::endl;
std::cout << "sizeof(long long) = " << sizeof(long long) << std::endl;
	
unsigned int ui = 10; //无符号的大小为4
long long l = -50; //带符号的大小为8

std::cout << "typeid(long long).name():" << typeid(long long).name() << std::endl;
std::cout << "typeid(ui + l).name():"<<typeid(ui + l).name() << std::endl;

在这里插入图片描述

从上面的例子可以看出,当带符号的大小>不带符号的大小,并且不带符号的全部范围都在带符号的范围内时,unsigned int转为long long型。

  • ii.若无符号的有不在有符号的范围内的,那么带符号的转换为无符号的,示意图如下:
    在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值