(四十)类型转换

简介:

已经知道,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   这两种强制转换有什么区别?

目录
相关文章
|
6月前
|
存储 安全 Java
程序与技术分享:C#值类型和引用类型的区别
程序与技术分享:C#值类型和引用类型的区别
45 0
|
6月前
|
编译器 C语言 C++
【海贼王编程冒险 - C语言海上篇】自定义类型:结构体,枚举,联合怎样定义?如何使用?
【海贼王编程冒险 - C语言海上篇】自定义类型:结构体,枚举,联合怎样定义?如何使用?
36 0
|
7月前
|
存储 Oracle Java
关于数据类型与变量的一些浅见
关于数据类型与变量的一些浅见
35 2
|
编译器 C++
【C++从0到王者】第三站:类和对象(中)赋值运算符重载
【C++从0到王者】第三站:类和对象(中)赋值运算符重载
53 0
|
7月前
|
存储 安全 编译器
【C++ 隐式转换】探究C++中隐式转换的奥秘
【C++ 隐式转换】探究C++中隐式转换的奥秘
203 0
|
编译器 测试技术 C语言
【C语言航路外传】隐式转换与优先级的那点事(你程序总是出bug的一个重要原因)
【C语言航路外传】隐式转换与优先级的那点事(你程序总是出bug的一个重要原因)
91 0
基本数据类型与运算符 查漏补缺
基本数据类型与运算符 查漏补缺
|
存储 算法 架构师
火车残骸和基本类型偏执问题解决方案
坏味道:缺乏封装。封装,将碎片式代码封装成可复用模块。但不同级别程序员对封装理解程度差异大,往往写代码的人认为自己提供了封装,但实际上,我们还是看到许多的代码散落在那里。
119 0
C语言中浮点数据类型(你学废了吗)
C语言中浮点数据类型(你学废了吗)
C语言中浮点数据类型(你学废了吗)
|
存储 编译器 C语言
第六周:数据类型
坚持自律是计算机中最强的天赋之一,加油!
108 0