当前位置:C++技术网 > 资讯 > 关于类型转换优先级的问题

关于类型转换优先级的问题

更新时间:2016-08-03 21:06:38浏览次数:1+次

C++中不同类型的数据进行操作的时候,类型转换的优先级是什么样的

例如int和unsigned中,unsigned的优先级更高


C++技术网解答:

C/C++类型转换是非常常用的。类型转换分为两种:显式转换和隐式转换。

1.显式转换

    这种方式也叫作强制转换。这是C/C++程序员最喜欢的类型转换方式,非常强大。强制转换可以让你在任何类型中自由转换,例如:

float d=12.12;
int a = (int)d;//a的结果为12
     这是应用强制转换的例子。如果不强制转换,编译器会告警,因为数据会丢失。而如果你强制转换,编译器就不会再告警,因为你是主动转换,表明你知道转换后的结果,所以编译器就不会再提醒你了。

    你还可以将一个整数转换为一个指针,例如:

int ptr = 0x10000000;
int *pInt = (int*)ptr;//得到指向0x10000000地址的指针
     你可以看到,强制转换非常的强大,非常的灵活。不过强大的背后,也就带来了隐患,如果一旦用错,就可能造成程序的崩溃,所以在C/C++程序中,经常出现内存读写错误。

    你可以在兼容的类型之间、不兼容的类型之间随意转换类型,但是你自己要确保结果是合理的,否则也得到无效的值。而且,你明显可以感觉到,强制类型转换目的性非常强,所以,强制类型转换,得到的是确定的类型。

    所以显示类型转换即强制转换不存在类型转换优先级问题。

2.隐式转换

    隐式类型转换则不是程序员主动为之的类型转换,而是编译器的默认执行的类型转换。既然是编译器默认执行的,在各种类型之间,必然有一个优先关系,好让编译器选择执行默认类型转换。

    出现隐式转换的情况通常是这样的:

int a = 12.12;//发生了隐式转换
     在变量的类型和得到的值类型不是同一个类型时,而且此时也没有强制转换,那么编译器就会执行隐式转换。这里目标类型时int,源类型为浮点型,因为12.12的精度比较低,可能是float,但是也可能是double,看编译器实现。

    计算机在做算术运算的时候,操作数需要是同一个类型,这是计算机的硬件电路特性决定的。如果某一天,硬件电路支持混合类型直接运算,那么就可以不用转换类型了。目前为止,还是需要先将操作数转为统一的类型,然后再做计算。

    只有相同的类型之间进行运算的时候,不用类型转换,兼容类型或者不同类型之间运算都会需要类型转换,如果无法转换,又不提供运算符重载、也不强制转换,那编译器只能报错了。

    既然在执行默认的类型转换的时候需要一个优先级顺序,那么这个优先级顺序是怎么样的呢?说实话,我没有见过这样的表,也没有想过完整的背这样的表,而且也没有意义。但是我们需要知道这么一个优先级顺序的存在,而且要知道优先级设计的原理。知道这些,就差不多了。在使用的时候,遇到一个,用一个,熟悉一个。实际上,很少有什么场合会大量执行复杂的默认类型转换的,这样的代码,谁敢看。最常见的就是些基本类型的默认转换。

    我们要知道,数据类型在内存表现为不同的长度的内存占用和存储形式。

    总的来说,长度长的,优先级高。否则如果占内存字节多的类型转为占内存低的类型,就会丢失数据。要么是数据高位被截断,要么是数据低位被截断,就造成数据丢失。比如long和int之间的转换,就遵守这个规则。

    另一方便,如果在内存占用长度一样的情况下,如果逻辑意义范围更广,优先级越高。比如int 和unsigned int,因为两者长度一致,但是int确表示的正负两个范围。如果在数学领域,int比unsigned int大一倍范围,只是计算机将这个类型具体化之后,范围是有限的。所以,unsigned int的正数范围是int的两倍,没有负数范围。所以从逻辑上讲,int范围更大。假如下面的情况:

int a = -10;
unsigned int b=1;
int c = a+b;//a+b运算时发生隐式的类型转换
     因为a的数值都很小,b却是负数,两者如何运算呢?如果你是设计规则的人,你如何设计?当然要让b向a靠。因为b根本就没有负数,无法表示a的值。另一种角度来看,也就是int的表示逻辑范围更大。所以小范围像大范围靠,大范围类型自然优先。这里说的其实是类型的兼容过程。

    总结下类型转换优先级的原理:兼容类型在隐式类型转换的时候会发生优先级问题。优先原则是:

1.兼容类型的逻辑范围越大越优先;

2.兼容类型占用内存大小越大的类型越优先;

3.兼容类型占用相同内存大小的两个类型,表示范围越大越优先;

4.不兼容类型,则无法进行隐式转换。

    所以,unsigned int > long 和  float > long long原则1),long>=int>=short>=char(原则2)  ,unsigned long>long(原则3),int <无法默认转换> char(原则4)

    以上是根据我的理解的设计原理逻辑演算推理得出的优先原则,不保证绝对正确,还需要结合编译器使用。我们在进行类型默认转换的时候,考虑的尽可能的减少数据损失,才有了上面的几个原则,或者还有更多,这里仅作一个参考,如果你觉得还有没有提到的,请补充。