标签: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库定义了istream向bool 转换的规则; 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语言风格的强制类型转换
标签:typeid 地址 规则 signed 风格 unsigned 表达 ptr 根据
原文地址:https://www.cnblogs.com/qzhj-pipeofnaturalrule/p/11962022.html