为了账号安全,请及时绑定邮箱和手机立即绑定

关于C++中的数据类型的自动转换?

关于C++中的数据类型的自动转换?

C++
收到一只叮咚 2019-07-07 04:04:28
哪些和哪些之间是可以自动转换的?就是说在函数调用时,所传参数与声明的参数类型不一致时做的转换,比如float和char,double和char,这些都可以吗?还有哪些?
查看完整描述

5 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

变量的数据类型是可以转换的。转换的方法有两种, 一种是自动转换,一种是强制转换。

自动转换

自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成。自动转换遵循以下规则:

1.若参与运算量的类型不同,则先转换成同一类型,然后进行运算。

2.转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。

3.所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。

4.char型和short型参与运算时,必须先转换成int型。

5.在赋值运算中,赋值号两边量的数据类型不同时, 赋值号右边量的类型将转换为左边量的类型。 如果右边量的数据类型长度左边长时,将丢失一部分数据,这样会降低精度, 丢失的部分按四舍五入向前舍入。

当参加算术或比较运算的两个操作数类型不统一时,将简单类型向复杂类型转换,
char(short) -> int(long) -> float -> double

下面程序段表示了类型自动转换的规则。

void main(){
float PI=3.14159;
int s,r=5;
s=r*r*PI;
printf("s=%d\n",s);
PI<--3.14159
s<--0,r<--5
s<--r*r*PI

显示程序运行结果:

float PI=3.14159;
int s,r=5;
s=r*r*PI;

本例程序中,PI为实型;s,r为整型。在执行s=r*r*PI语句时,r和PI都转换成double型计算,结果也为double型。但由于s为整型,故赋值结果仍为整型,舍去了小数部分。

 


查看完整回答
反对 回复 2019-07-08
?
绝地无双

TA贡献1946条经验 获得超4个赞

C++不是类型安全的。
分别为:static_cast , dynamic_cast , const_cast , reinterpret_cast
2、四种转换的区别:
static_cast:可以实现C++中内置基本数据类型之间的相互转换。
const_cast: const_cast操作不能在不同的种类间转换。相反,它仅仅把一个它作用的表达式转换成常量。它可以使一个本来不是const类型的数据转换成const类型的,或者把const属性去掉。
reinterpret_cast: 有着和C风格的强制转换同样的能力。它可以转化任何内置的数据类型为其他任何的数据类型,也可以转化任何指针类型为其他的类型。它甚至可以转化内置的数据类型为指针,无须考虑类型安全或者常量的情形。不到万不得已绝对不用。
dynamic_cast: 其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。不能用于内置的基本数据类型的强制转换。dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过

查看完整回答
反对 回复 2019-07-08
?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

转换的含义是通过改变一个变量的类型为别的类型从而改变该变量的表示方式。为了类型转换一个简单对象为另一个对象你会使用传统的类型转换操作符。比如,为了转换一个类型为doubole的浮点数的指针到整型:
代码:
int i;
double d;
i = (int) d;或者:i = int (d);
对于具有标准定义转换的简单类型而言工作的很好。然而,这样的转换符也能不分皂白的应用于类(class)和类的指针。ANSI-C++标准定义了四个新的转换符:'reinterpret_cast', 'static_cast', 'dynamic_cast' 和 'const_cast',目的在于控制类(class)之间的类型转换。
代码:
reinterpret_cast<new_type>(expression)
dynamic_cast<new_type>(expression)
static_cast<new_type>(expression)
const_cast<new_type>(expression)


 


查看完整回答
反对 回复 2019-07-08
?
交互式爱情

TA贡献1712条经验 获得超3个赞



C  风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:



TYPE b = (TYPE)a


C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。


const_cast,字面上理解就是去const属性。

static_cast,命名上理解是静态类型转换。如int转换成char。

dynamic_cast,命名上理解是动态类型转换。如子类和父类之间的多态类型转换。

reinterpreter_cast,仅仅重新解释类型,但没有进行二进制的转换。

4种类型转换的格式,如:



TYPE B = static_cast(TYPE)(a)


const_cast


去掉类型的const或volatile属性。



struct SA {

int i;

};

const SA ra;

//ra.i = 10; //直接修改const类型,编译错误

SA &rb = const_castSA&>(ra);

rb.i = 10;


static_cast


类似于C风格的强制转换。无条件转换,静态类型转换。用于:

1. 基类和子类之间转换:其中子类指针转换成父类指针是安全的;但父类指针转换成子类指针是不安全的。(基类和子类之间的动态类型转换建议用dynamic_cast)

2. 基本数据类型转换。enum, struct, int, char, float等。static_cast不能进行无关类型(如非基类和子类)指针之间的转换。

3. 把空指针转换成目标类型的空指针。

4. 把任何类型的表达式转换成void类型。

5. static_cast不能去掉类型的const、volitale属性(用const_cast)。



int n = 6;

double d = static_castdouble>(n); // 基本类型转换

int *pn = &n;

double *d = static_castdouble *>(&n) //无关类型指针转换,编译错误

void *p = static_castvoid *>(pn); //任意类型转换成void类型


dynamic_cast


有条件转换,动态类型转换,运行时类型安全检查(转换失败返回NULL):

1. 安全的基类和子类之间转换。

2. 必须要有虚函数

3. 相同基类不同子类之间的交叉转换。但结果是NULL。



class BaseClass {

public:

int m_iNum;

virtual void foo(){};

//基类必须有虚函数。保持多台特性才能使用dynamic_cast

};

class DerivedClass: public BaseClass {

public:

char *m_szName[100];

void bar(){};

};

BaseClass* pb = new DerivedClass();

DerivedClass *pd1 = static_castDerivedClass *>(pb);

//子类->父类,静态类型转换,正确但不推荐

DerivedClass *pd2 = dynamic_castDerivedClass *>(pb);

//子类->父类,动态类型转换,正确

BaseClass* pb2 = new BaseClass();

DerivedClass *pd21 = static_castDerivedClass *>(pb2);

//父类->子类,静态类型转换,危险!访问子类m_szName成员越界

DerivedClass *pd22 = dynamic_castDerivedClass *>(pb2);

//父类->子类,动态类型转换,安全的。结果是NULL


reinterpreter_cast


仅仅重新解释类型,但没有进行二进制的转换:

1. 转换的类型必须是一个指针、引用、算术类型、函数指针或者成员指针。

2. 在比特位级别上进行转换。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。但不能将非32bit的实例转成指针。

3. 最普通的用途就是在函数指针类型之间进行转换。

4. 很难保证移植性。



int doSomething(){return 0;};

typedef void(*FuncPtr)();

//FuncPtr is 一个指向函数的指针,该函数没有参数,返回值类型为 void

FuncPtr funcPtrArray[10];

//10个FuncPtrs指针的数组 让我们假设你希望(因为某些莫名其妙的原因)把一个指向下面函数的指针存入funcPtrArray数组:

funcPtrArray[0] = &doSomething;

// 编译错误!类型不匹配,reinterpret_cast可以让编译器以你的方法去看待它们:funcPtrArray

funcPtrArray[0] = reinterpret_castFuncPtr>(&doSomething);

//不同函数指针类型之间进行转换


总 结


去const属性用const_cast。

基本类型转换用static_cast。

多态类之间的类型转换用daynamic_cast。

不同类型的指针类型转换用reinterpreter_cast。




查看完整回答
反对 回复 2019-07-08
  • 5 回答
  • 0 关注
  • 430 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信