已经知道,int,double,short,char,long,float等多个类型,其中有整型,也有浮点类型。然而,在实际应用中,经常会涉及到类型转换问题。
例如
double a=13.33333333;
float b=a;
这个时候,实际上就是把double a的值赋值给float b,而又因为变量a和变量b的精度不同,所以在赋值的时候,C++需要将其类型进行转换。
又比如,两个类型为short的变量相加的结果,可能和2个long相加的结果不同(因为可能存在溢出,例如unsigned short的最大值为65535,如果2个short整型的65535相加,且将结果赋值给short类型的变量,新变量的数值必定不是65535*2)。如代码:
#include <iostream> int main() { using namespace std; short a = 32767; short b,c; b = a + a; c = a*a; cout << a << endl; cout << b << endl; cout << c << endl; system("pause"); return 0; }
输出结果为:
32767 -2 1
因此,需要注意类型的转换。
在以下三种情况,C++自动执行类型的转换(即无需我们进行转换)
①将一种算数类型的值赋给另外一种算数类型的变量时,C++自动进行转换。例如将int a=54321赋值给short b时,b的值则不为54321。但是如果将short b=1234赋值给int a时,a的值依然为1234。
即表示范围更大的类型(如int)赋值给表示范围更小的类型(如short)时,数值可能发生变化。超出部分通常只复制靠右边的部分。
表示范围更小的类型(如char)赋值给表示范围更大的类型(如short)时,数值不会发生变化,只是会占用更多的字节。
浮点类型转换成整型(如double转换为int),则自动丢失小数部分。
其他类型赋值给boo时,非0值被转换为true(1),0值为false(0)。
上代码:
#include <iostream> int main() { using namespace std; cout.setf(ios_base::fixed, ios_base::floatfield); double a = 1.123456789; float b = a*1e4; short c = a*1e4; float e = a; short f = a; cout << "已知a=1.123456789,变量类型为double\n"; cout <<"a*10000= "<< a * 1e4<< endl; cout << endl; cout << "b=a*10000,变量类型为float\n"; cout << "b = " << b << endl; cout << endl; cout << "c=a*10000,变量类型为short\n"; cout << "c = " << c << endl; cout << endl; cout << "e=a,变量类型为float" << endl; cout << "e*10000= " << e*1e4 << endl; cout << endl; cout << "f=a,变量类型为short" << endl; cout << "f*10000= " << f*1e4 << endl; bool g = a, h = a * 10000; cout << "g和h的类型为bool,其中g=a,h=a*10000\n"; cout << "g = " << g << endl; cout << "g*10000= " << g * 10000 << endl; cout << "h = " << h << endl; system("pause"); return 0; }
输出结果为:
已知a=1.123456789,变量类型为double a*10000= 11234.567890 b=a*10000,变量类型为float b = 11234.568359 c=a*10000,变量类型为short c = 11234 e=a,变量类型为float e*10000= 11234.568357 f=a,变量类型为short f*10000= 10000.000000 g和h的类型为bool,其中g=a,h=a*10000 g = 1 g*10000= 10000 h = 1
我们可以从输出结果看出,一个数,经过赋值,然后转换类型,再相乘,得出5个不同的结果。
②表达式中包含不同的类型时,C++会自动进行转换。
例如bool,char,short,unsigned char,signed short的值被转换为int(其中bool的true被转换为1,false被转换为0)。这些转换被称为整型提升。
另外,这种转换不会丢失数据。
例如,short被转换为int,假如unsigned short的范围大于int,则unsigned short被转换为unsigned int,以避免损失数据。而wchar_t在不损失数据的情况下,依顺序转换为int,unsigned int,long,unsigned long,具体转换为哪个,取决于哪个的宽度能最先容纳wchar_t。
而在计算时,会优先将范围小的转换为范围大的类型,再进行计算。
例如9/5.0,则先把int类型的9转换为double的9.0(因为5.0的类型是double),然后再计算。
这是因为double的范围比int更大,如果有long double存在,则转换为long double再计算,如果没有这2个,只有float,则转换为float,再进行计算。
总之,有浮点数参与的时候,转换为浮点类型最大的浮点数的浮点类型,再计算,如果没有浮点数,则进行整型提升(即转为int或者更大)再进行计算。
③传递参数时的转换。
没看懂……
除了以上三种自动转换,还可以进行强制转换。
具体使用方式如下:
long (a);
(long) a;
即——(类型) 值;或者 类型 (值) 。
如果a原本是int a,这两种方式都可以强制将int a显示为long a。
强制转换类型不是改变原来类型的值,例如int a依然是int a,只不过long (a)则是long类型的a了。
如代码:
#include <iostream> int main() { using namespace std; double a = 1.33; cout << "double a= " << a << endl; cout << "long (a)= " << long(a) << endl; cout << "double a= " << a << endl; cout << "(long) a= " << (long)a << endl; system("pause"); return 0; }
输出结果为:
double a= 1.33 long (a)= 1 double a= 1.33 (long) a= 1
可以发现,虽然有个long (a)在中间,也有个(long) a在最后,但是并没有改变变量a的类型。这种可以理解为创建了一个新值,他的类型为long。
另外C++还有4个强制类型转换运算符,例如其中的一种是static_cast<类型名typename> (值value)。这种可以用来满足不同的运算。
不过按照文中说明,强制类型转换可能是危险的。具体使用的话,需看情况而言。
就static_cast而言,可以如下使用。
代码:
#include <iostream> int main() { using namespace std; double a = 1.33; cout << "a= " << a << endl; cout << "static_cast<int> (a)= " << static_cast<int> (a) << endl; system("pause"); return 0; }
输出结果:
a= 1.33 static_cast<int> (a)= 1
static_cast<int>(a) 和 (int)a 这两种强制转换有什么区别?