[C++] 类型转换

目录

1. 隐式转换

1.1 算术转换

1.1.1 整型提升

1.1.2 有、无符号类型的转换

1.2 其他隐式转换

2. 显式转换

2.1 static_cast(expression)

2.2 const_cast(expression)

2.3 reinterpret_cast(expression)

2.4 dynamic_cast(expression)


1. 隐式转换

概念:程序自动执行,无须程序员的介入的类型转换。

转换情况:

        1.比int类型小的整型值会提升为大的整数类型

        2.条件语句中,非布尔值转化为布尔值

        3.赋值语句中,右侧的运算对象转化为左侧的运算对象

        4.算术运算或关系运算的运算对象,都要转化为同一种类型

        5.函数调用也会发生类型转换。

1.1 算术转换

概念:算术类型间的互相转换。3

原则:转移后的类型能容纳原类型所有可能的值,小----->大。(牢记!!!!算术转化大都是如此!!!)

1.1.1 整型提升

整型提升:把小整数类型转化为大整数类型

对于bool、char、signed char、unsigned char、short、unsigned shot 等数据类型小整型,会转化为 int型 大整型,所以在位运算中,会先将8位的unsigned char转化为32位的int型。

对于较大的char型,会提升为 int、unsigned int、long、unsigned long、long long 、unsigned long long 中最小的一种类型。

1.1.2 有、无符号类型的转换

这里以+运算符为例:

有符号类型+有符号类型  /  无符号类型+无符号类型 (类型不一样,有无符号是一样的):都会先进行整型提升,1. 如果类型匹配,则无需进一步转换,2. 如果不匹配,则将小的转化为大的类型。

无符号类型+有符号类型(无符号类型>=有符号类型):则 有符号类型 转化为 无符号的 。

比如:int 和 unsigned int,int就会转化为unsigned int。注意:如果int是有负号,则转化为无符号,要进行取模处理。

无符号类型+有符号类型(无符号类型<有符号类型):要看机器里它们的大小比较结果,1.如果 无符号类型 的所有值都能存放在 有符号类型 中,则 无符号类型 转化为 有符号类型 ,2.如果不能,则 有符号类型 转化为 无符号类型 。

比如:long(32) 和 unsigned int(16) ,并且它们两在机器里大小相同,则long转化为unsigned int ,若long 类型比 int 所占空间大,则unsigned int 转化为 long

short sval;
char cval;

unsigned long ulval;
int ival;

sval+cval; // 两个都提升为int
ival+ulval; // 将ival转化为ulval

1.2 其他隐式转换

数组转化为指针:int a[4];   int *p=a;   // int *p=&a[0];

指针的转换

        1.指向常量整数值0,以及字面值nullptr的指针,可以转换为任意指针类型

        2.指向任意非常量的指针都能转化为void*

        3.指向任意对象的指针能转化为const void*

        4.有继承关系的类型间也能进行指针转换

转换成布尔类型:在条件语句中,会将算术类型转化为指针类型。

转换成常量:就是在[C++] const修饰符那一章节里所说的,指向常量的指针,const int*p,可以不同遵循指针所指向的类型相等的定理,就是这里发生了隐式转换,将const int *p=&i ,int i 转换成了常量类型。

类类型定义的转换:由编译器自动执行的转换,只能执行一种类类型的转换,如:string s="value" 就是将const char*类型转换为了string类型,while(cin>>s) 就是将cin转换为了布尔值。

2. 显式转换

形式:cast-name<type>(expression)

四种显式转换:static_cast<type>() 、dynamic_cast<type>() 、const_cast<type>() 、reinterpret_cast<type>()

2.1 static_cast<type>(expression)

明确定义的类型转换,只要不包含底层const,都可以使用这个,它可以把大的算术类型强制转化为小的算术类型。

int j=10;
double i=10.5;
double slope=static_cast<double>(j) /i;

注意:在对void*型指针进行强制转换时,需要保证其转换回来的类型要与原类型一样。不然会发生未定义的错误。

int d=10;
void *p=&d;
int *ip=static_cast<int*>(p);  // 不能是其他的类型如 double *ip = static_cast<double *> (p);

2.2 const_cast<type>(expression)

只能改变运算对象的底层const。只能改变常量属性,不能改变变量类型。

type只能是指针或引用类型。

const char *pc="hello";
char *p=const_cast<char*>(pc);  // 正确,p='h'

string s1;
const string &s=const_cast<const string&>(s1);

常常用于函数重载的上下文中。

2.3 reinterpret_cast<type>(expression)

指针之间的类型转换,建议不要使用,如果对涉及的类型和编译器实现转换过程不了解的话,很容易出错。

int *ip;
char *pc=reinterpret_cast<char*>(ip);
//像这里,我们必须牢记这里pc获取的是一个存储int类型的地址,不能把它当做char*来看待。

2.4 dynamic_cast<type>(expression)

类与类之间的类型转换,以后再补上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值