C++类型转换

隐式转换

  C++在对表达式求值时(包括赋值、算术运算、条件表达式),如果表达式中存在不同类型的变量,则会进行隐式转换。隐式转换会将所有变量转换成相同类型,并且,尽可能避免精度丢失。

一 赋值转换
  1. 当我们把一个非布尔类型的算术赋值给布尔类型时,初始值为0,则结果为false,否则结果为true。同样,布尔类型赋给算术类型时,true为1,false为0。如果是指针类型,指针为空则为false。

    bool flag = 1.22;	//	flag == true
    int num = flag;     //  num == 1
    
    int *p = nullptr;
    if(p)	//	false
    

  1. 当我们把一个浮点数赋给整数类型时,进行了近似处理。结果值将仅保留浮点数中小数点之前的部分。

    int num = 3.14;         //  num == 3
    double dVar = num;      //  dVar == 3.000000
    

  1. 当我们把一个整数值赋给浮点类型时,小数部分记为0。如果该整数所占的空间超过了浮点类型的容量,精度可能有损失。

    int num = 3.14;         //  num == 3
    double dVar = num;      //  dVar == 3.000000
    
    long nMax = 0x7fffffff;      //  int所能表示的最大值: 2^31-1 == 2147483647
    float fVar = nMax + 2;      //  fVar == -2147483648.000000
    

  1. 当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。例如,8比特大小的unsigned char 可以表示0到255区间的值,如果我们赋了一个区间以外的值,则实际的结果是该值对256取模后的余数。因此,把-1赋给8比特大小的unsigned char 所得的结果是255。

    unsigned char c1 = 256;      //  c1 == 0
    unsigned char c2 = -1;       //  c2 == 255			-1 % 2^8 = 255
    

  1. 当我们赋给带符号类型一个超出它表示范围的值时,结果是未定义的。此时,程序可能继续工作、可能崩溃,也可能生成垃圾数据。

    int num = 0x7fffffff + 1;    //  Clion中,num == -2147483648
    

二 算术转换
  • 整形提升

    整形提升负责把小整数类型转换成较大的整数类型。

  • 无符号类型的运算对象

    先进行整形提升:char、bool、unsigned char、short、unsigned short等提升为int,false 提升为 0,true提升为 1。
    如果其中无符号类型不小于带符号类型,那么带符号的运算对象转换成无符号的;
    如果有符号类型大于无符号类型,此时转换的结果依赖于机器。如果无符号类型的所有值都能存在该带符号的类型中,则无符号类型的运算对象转换成带符号类型。如果不能,那么带符号类型的运算对象转换成无符号类型。例如,如果两个运算对象类型分别是 long 和 unsigned int, 并且 int 和 long 的大小相同,则 long 类型的运算对象转换成 unsigned int 类型;如果 long 类型占用的空间比 int 更多,则 unsigned int 类型的运算对象转换成 long 类型。

例子:

bool    flag;   char            cval;
short   sval;   unsigned short  usval;
int     ival;   unsigned int    uival;
long    lval;   unsigned long   ulval;
float   fval;   double          dval;

3.14L + 'a';	//	'a' 提升成int, 然后int值转换成 long double
dval + ival;	//	ival 转换成 double
dval + fval;	//	fval 转换成 double
cval + fval;	//	cval 提升成 int, 然后该 int 的值转换成 float
sval + cval;	//	sval 和 cval 都提升成 int
cval + lval;	//	cval 转换成 long
ival + ulval;	//	ival 转换成 unsigned long
usval + ival;	//	根据 unsigned short 和 int 所占空间的大小进行提升
uival + lval;	//	根据 unsigned int 和 long 所占空间的大小进行提升

三 其它隐式转换

  1. 数组转换成指针
在大多数用到数组的表达式中,数组会自动转换成指向数组首元素的指针,如将数组作为数组函数等
int ia[10];    	 //  Clion中,num == -2147483648
int* ip = ia;    //  ia转换成指向数组首元素的指针

但是,当数组被用作 decltype 关键字的参数,或者作为取地址符(&)、sizeof 及 typeid 等运算符的运算对象时,上述转换不会发生。特别是,当数组作为引用传递给函数调用时,数组名没有转换成指针。
  1. 指针转换
(1) 0 或者字面值 nullptr 能转换成任意指针类型;
(2) 指向任意非常量的指针能转换成 void*; 指向任意常量对象的指针能转换成 const void*;
(3) 父类指针能指向子类对象;
  1. 转换成常量
C++允许将 指向非常量类型的指针和引用 转换成 指向相应的常量类型的指针和引用。
int i;
const int &j = i;	//	非常量转换成 const int 的引用
const int *p = &i;	//	非常量的地址转换成 const 的地址
  1. 类类型定义的转换
如: iostream类型能转换成bool类型,你可能碰到过这样的代码

string s;
while (cin >> s)
{
   ...	//	输入EOF则结束
}
   
while (cout << "a\n")	//	这样就会一直输出 'a'
{
   cout << cout.good() << endl;
   //cout.setstate(std::ios_base::failbit);	这样就能使循环终止
   cout << cout.good() << endl;
}

IO库定义了从 istream、ostream 向布尔值转换的规则,所得到的布尔值由流的状态来决定,如果流出错或者结束,就会返回false。

显式转换(强制转换)

一 C 语言显示转换

int i = 1, j = 2;
double slope = (double)i / j;	

或者 C++形式
double slope = double(i) / j;

二 C++ 显示转换

c++进行强制类型转换时,它定义了四种分类,分别是 static_cast、dynamic_cast、const_cast、reinterpret_cast。
语法如下:
  cast-name(expression); 其中type是类型,expression是表达式。

  1. static_cast
用于具有明确定义的类型转换
double slope = static_cast<double>(j) / i;
int i;

常用之处:
(1) 将一个较大的算术类型赋值给较小的类型时;
(2) 将一个非常量对象的地址存入 void*, 再通过 static_cast 取回;
  1. dynamic_cast
用于 运行时类型识别(run-time type identification, RTTI), 将基类的指针或引用安全地转换成派生类的指针或引用。

dynamic_cast<type*>(e);
dynamic_cast<type*>(e);
dynamic_cast<type*>(e);

if (Derived *dp = dynamic_cast<Derived*>(bp))
{
   //	使用dp指向Derived对象
}
else
{
   //	使用bp指向Base对象
}
  1. const_cast
去除运算对象的底层const(如果一个指针是const, 并且它指向的对象也是const。则指针是顶层const, 这个对象是底层const)。

const char *pc = "string";
char *p = const_cast<char*>(pc);	//	此时可以通过 p 更改 “string” 的内容
  1. reinterpret_cast
reinterpret_cast 通常为运算对象的位模式提供较低层次上的重新解释。如:

int num = 'a';
int *pn = &num;
char *pc = reinterpret_cast<char*>(pn);
string str(pc);
printf("%s\n", str);	// 输出 'a'

相当于
char *pc = (char*) pn;	//	C语言写法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值