C++中的类型转换
2015-07-24 09:48
363 查看
C++中类型转换的注意事项
unsigned intu=10;
int i=-42;
cout<<i+i<<endl;
cout<<u+i<<endl;
第一行输出的是-84,按照我们预定的结果输出了,第二行呢?结果为429497264,结果挺出人意料的。出现这样的原因是i会首先被转换为unsigned int类型数据,然后和u执行加法运算。-42转换为unsigned int类型数据后为429497254,加上10后输出结果。这就是隐式类型转换的缺点,为了能够很好地避免这类问题,很有必要将隐式类型转换的法则弄清楚。
基本法则:在数学运算中的隐式类型转换会尽量保持数据的精度。隐式类型转换主要发生在下面几种情况:
[1] 在大多数表达式中,凡是比int小的数据类型会首先转换为大点的数据类型;
在表达式中,bool, char,signed char, unsigned char, short 和unsigned short都会转换为int,如果这些类型的所有值都在int型数据的范围内,否则就转换为unsigned int。
对于一些扩展char类型(wchar_t,char16_t, char32_t),会尽量在int, unsigned int, long, unsigned long, long long 和unsignedlong long中找适合的最小的数据类型。
例子:
char i=0x7D;
i<<8;//i会首先转换为int,然后再执行向左移位操作。
[2] 在真假表达式中,其他类型的数据都要转换为bool;
float fval = 0.1;
if(fval){/*….*/} //fval会转换为bool,规则为非0即为真
[3] 在赋值语句中,赋值语句右边的数据转换为左边数据的类型;
[4] 在数学表达式中,不同类型的操作数都将转换为相同的数据类型;
首先对比较小的数据类型转换为int或者unsigned int;然后再进行其他的转换。如果转换后的两个操作数的类型的符号性(signedness)一样,即同为signed 或unsigned,则直接将两个操作数中较小的类型转换为较大的类型。如果符号性不同,则分为两种情况,一种是有符号操作数的类型比无符号操作数的类型大,则将无符号操作数转换为有符号操作数的类型;另一种是无符号操作数的类型比有符号操作数的类型大或者相同,则将有符号操作数转换为无符号操作数的类型。
[1] 常量0或者nullptr可以被转换为任意的指针类型;
[2] 一个指向nonconst数据类型的指针可以被转换为void *;
[3] 任何类型的指针都能够转换为const void*.
const类型转换:
我们可以将一个指向nonconst数据的指针转换为指向const数据的指针;反过来不行。
l 当获取void*指针指向的对象的时候,有用;
int i=2,j=9;
double slope = static_cast<double>(j)/I;
void *p=&slope;
double *db=static_cast<double*>(p);
const char *p;
char *p =const_cast<char*>(pc);
隐式类型转换
基本数据类型的隐式转换
隐式类型转换(implicitconversion)的名称的来源是:这种类型转换由编译器自己完成,没有编程者的参与。虽然减少了编程者的繁琐工作量,但是某些时候会出现令人很奇怪的结果;如下例:unsigned intu=10;
int i=-42;
cout<<i+i<<endl;
cout<<u+i<<endl;
第一行输出的是-84,按照我们预定的结果输出了,第二行呢?结果为429497264,结果挺出人意料的。出现这样的原因是i会首先被转换为unsigned int类型数据,然后和u执行加法运算。-42转换为unsigned int类型数据后为429497254,加上10后输出结果。这就是隐式类型转换的缺点,为了能够很好地避免这类问题,很有必要将隐式类型转换的法则弄清楚。
基本法则:在数学运算中的隐式类型转换会尽量保持数据的精度。隐式类型转换主要发生在下面几种情况:
[1] 在大多数表达式中,凡是比int小的数据类型会首先转换为大点的数据类型;
在表达式中,bool, char,signed char, unsigned char, short 和unsigned short都会转换为int,如果这些类型的所有值都在int型数据的范围内,否则就转换为unsigned int。
对于一些扩展char类型(wchar_t,char16_t, char32_t),会尽量在int, unsigned int, long, unsigned long, long long 和unsignedlong long中找适合的最小的数据类型。
例子:
char i=0x7D;
i<<8;//i会首先转换为int,然后再执行向左移位操作。
[2] 在真假表达式中,其他类型的数据都要转换为bool;
float fval = 0.1;
if(fval){/*….*/} //fval会转换为bool,规则为非0即为真
[3] 在赋值语句中,赋值语句右边的数据转换为左边数据的类型;
[4] 在数学表达式中,不同类型的操作数都将转换为相同的数据类型;
首先对比较小的数据类型转换为int或者unsigned int;然后再进行其他的转换。如果转换后的两个操作数的类型的符号性(signedness)一样,即同为signed 或unsigned,则直接将两个操作数中较小的类型转换为较大的类型。如果符号性不同,则分为两种情况,一种是有符号操作数的类型比无符号操作数的类型大,则将无符号操作数转换为有符号操作数的类型;另一种是无符号操作数的类型比有符号操作数的类型大或者相同,则将有符号操作数转换为无符号操作数的类型。
其他数据类型的隐式转换
指针的转换:[1] 常量0或者nullptr可以被转换为任意的指针类型;
[2] 一个指向nonconst数据类型的指针可以被转换为void *;
[3] 任何类型的指针都能够转换为const void*.
const类型转换:
我们可以将一个指向nonconst数据的指针转换为指向const数据的指针;反过来不行。
显式类型转换
static_cast
l 当需要将一个大类型转换为小类型时,有用;l 当获取void*指针指向的对象的时候,有用;
int i=2,j=9;
double slope = static_cast<double>(j)/I;
void *p=&slope;
double *db=static_cast<double*>(p);
const_cast
去除一个对象的const性质,在用的时候注意如果原对象本质上不是一个常量,通过显式类型转换能够获得改变该对象的权力;如果原对象本质上是一个常量则这样做会产生意想不到的结果。const char *p;
char *p =const_cast<char*>(pc);
reinterpret_cast
相关文章推荐
- C++对象模型3--无重写的单继承
- 1.C++面向对象程序设计
- 普通的年轻状态机,纯C语言
- C++实现道格拉斯-普克法压缩矢量数据
- C语言堆栈入门——堆和栈的区别
- c语言中volatile关键字的含义
- char, signed char, and unsigned char in C++
- Effective C++ 学习记录
- 用C语言操作MySQL数据库的通用方法
- C++ map 的基本操作和使用
- C语言(2)--牛顿迭代法、舍罕王的赏赐、解两个不等式、枚举类型变量输出三原色全排列
- C++面向对象编程(五)之 运算符重载
- C++对象模型6--对象模型对数据访问的影响
- UVa10129 判断有向图中是否存在欧拉回路
- 一个关于c++数值转换的小程序的思考
- 《C++编程思想》(第二版)第2章 对象的创建和使用(习题及答案)
- 学习笔记:c语言中词法陷阱
- C++11新特性
- Friends
- C++“隐藏实现,开放接口”的实现方案