码迷,mamicode.com
首页 > 编程语言 > 详细

C++ 类型转换

时间:2019-11-30 13:59:53      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:typeid   地址   规则   signed   风格   unsigned   表达   ptr   根据   

类型转换: C++中, 如果两种类型相关联, 如果程序需要一种类型的运算对象时,可以用另一种关联类型的对象或值来代替。 也就是说,这两种类型可以互相转换, 即两种类型是关联的。

int  ival = 3.541+ 3;   编译器会警告 运算会损失精度

 

隐式类型转换: C++不会将两个数直接相加,  而是先根据类型转换规则 将对象转换成统一的类型后再求值。隐式类型转换: 这种类型转换是编译器自动执行, 不需要程序员介入

表达式中先把 int转换成double,  计算结果为double,  然后在把double转换成int  赋值给变量ival

 

隐式转换的情况: 下面 编译器会自动转换对象的 类型。

大多数表达式中,  int小的类型首先提升成较大的整数类型

作为条件的表达式中, 非布尔值转换成布尔值

初始化中,

如果算术运算或关系运算的对象多种类型, 需要转换成同一种类型

 

C++常规类型自动类型转换规则

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

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

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

4)否则,到这里说明两个操作数都是整型,因此 进行整型提升。

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

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

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

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

 

 

算术转换: 是把一种算术类型转换成另一种算术类型。

定义了类型转换层次:运算对象转换成最宽的类型; 既有整数类型又有浮点类型时, 整数值转换成浮点类型。

 

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

对于bool/ char  signed char  unsigned char  short  unsigned short等类型来说, 只要他们所有可能的值都能存在int里,他们就会提升成int类型;否则 提升成unsigned类型。

 

较大的char类型(wchar_t  char16_t  char32_t)提升成 int   unsigned int    long  unsigned long  long long     unsigned long  long 中最小的类型, 前提是转换后的类型能容纳原类型所有可能的值。

 

无符号类型的运算对象:P142

 

要想理解算术转换,办法之一就是研究大量的例子。:

P142

 

其他隐式类型转换:几种情况:

1、  数组转换成指针 在大多数用到数组的表达式中,  数组会自动转换成指向数组首元素的指针。

int ia[10];

int  *p=ia;

 

当数组被用作decltype 的参数, 或 作为 取地址符&   sizeof typeid的运算对象时,上诉转换不执行

指针转换: 常量整数值0 或字面值nullptr能转换成任意指针类型;  指向任意非常量的指针能转换成void* ; 指向任意对象的指针能转换成 const void *

转换成bool类型: 指针或  算术类型 的值为0   转换结果为false  否则转换为true

转换成常量: 允许将 指向非常量类型的指针 转换成 指向相应的常量类型的指针。引用也是如此。

               如果一个类型为T , 那么, 我们就能将 指向T的指针或引用 分别转换成指向const  T的指针或引用。但是反过来不存在, 因为试图删除底层const

int i ;

const int &j=i;

const int *p=&i;

int &r= j, *q=p;  错误  不能将const转换成非常量

 

类类型定义的转换:类类型能定义由编译器自动执行的转换。不过编译器一次只能执行一个种类类型的转换。

string s,  t="a  value";       // 字符串字面值转换成 string类型。

while( cin<< s)       IO库定义了istreambool 转换的规则 bool值由输入流的状态决定: 如果最后一次读入成功, bool值为true, 最后一次读取不成功,则 为false

 

显示转换: 

 

int  i, j;

double  slope = i / j;  使用这种方法将i/ j 显式的转换成double叫强制类型转换

 

命名的强制类型转换一个命名的强制类型转换具有以下 形式如下:

cast_name<type>(expression);   type是目标类型, expression是要转换的值。 如果type是引用类型, 则结果是左值。

 

cast_name 包含:

static_cast     任何具有明确定义的类值转换, 只要不包含底层const, 都可以用static-cast

double slope = static_cast<double>(j)/i;   //  j强制转换成double类型进行浮点数计算,  i将被转换为double类计算。

static_cast 对于编译器无法自行执行的类型转换也很有用;例如: 我们用static_cast 找回存在于void* 指针中的值:

void  *p= &d;     任何非常量对象的地址都能存入void*

double  *dp =static_cast<double*>(p);  void*转换会初始的指针类型。

 

 

dynamic_cast   

 

const_cast   只能改变运算对象的底层const

const  char  *pc;

char  *p = const_cast<char*>(pc);      但是通过p 写值是未定义的行为。

把常量转换成非常量的行为: 去掉 const性质( cast away the const)。一旦我们去掉了某个对象的const性质,编译器就不再阻止我们对该对象进行写操作了。如果对象本身不是一个常量, 使用强制类型转换获得写操作权限是合法的, 如果对象是个常量,再使用const_cast 执行写操作就会产生未定义的后果。

 

只有const_cast 能改变表达式的常量属性,其他都是未定义的。

不能用const_cast 改变表达式的类型。

 

reinterpret_cast   为运算对象的位模式提供较低层次上的重新解释。

 

 

建议: 避免强制类型转换。

 

旧式的强制类型转换:

早期版本C++中, 显式强制类型转换包含两种形式:

Type  (expr);     // 函数形式的强制类型转换

(type)  expr;    C语言风格的强制类型转换

C++ 类型转换

标签:typeid   地址   规则   signed   风格   unsigned   表达   ptr   根据   

原文地址:https://www.cnblogs.com/qzhj-pipeofnaturalrule/p/11962022.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!