C++中的内置类型以及类型转换

在开始介绍类型转换之前,我们先了解一下C++中的数据类型,不太清楚的朋友可以先看下第一部分的介绍。

1.C++中的内置类型

C++中的内置内型主要分为基本类型和复合类型。

1.1基本类型

基本类型主要指整数和浮点数,而整数又可以分为short,int,long以及C++11 标准新增的long long,通常把以上几种整数类型以及char统称为整型,因为它们没有小数点。而每一种整型又存在有符号整型以及无符号整型,默认均为有符号整型,如果在类型名前面加上unsigned关键字,则可以把它变为无符号整型,char类型是例外,不带unsigned关键字的char没有明确限定是有符号还是无符号,因此需要明确表示带符号还是不带符号时需要加上signed或者unsigned关键字。其中int作为C++默认能够表示某整数常量的类型。
浮点类主要是指有小数点的数字,比如23.11,或者1.202E+8。C++中的浮点类型主要包括float,double以及long double。其中double作为C++默认能够表示小数常量的类型。
各种类型的定义如下:
//整型变量的定义
char ch_va='a';
signed char s_ch_va='v';
unsigned char u_ch_va='s';
short sh_va=-23;
unsigned short u_sh_va=132;
int int_va=762;
unsigned u_int_va=841;
long long_va=2312312;
unsigned long u_long_va=492831;
long long llong_va=377198723;
unsigned long long u_llong_va=76678982;

1.2复合类型

符合类型是由上述的基本整型和浮点型创建的,比基本类型更复杂一点。比如数组,结构,枚举,共用体都属于复合类型。以下是个别复合类型的定义,可以看出复合类型中可以包括一种或者几种基本类型,甚至可以是复合类型本身。
//复合类型
//结构
struct CPlusPlus
{
	int m_value;
	char flag;
	double distance;
};
//枚举
enum Star
{
	earth=0,sun=1,moon=2
};

2.类型转换

如上所述,C++中的类型如此之多,当不同类型的数据进行运算时会发生什么?C++中的类型转换包括自动转换和强制转换两种,自动转换无需我们干涉,编译器会帮我们执行,而强制类型转换则根据我们自己的意图有选择性的转换数据。

2.1类型自动转换

首先看下自动转换,什么时候会发生自动转换?

2.1.1 将一种算数类型的值赋值给另外一种算数类型的变量时,C++将对值进行转换。

比如当变量进行初始化和赋值的时候。可以允许把一种算数类型的值赋值给另外一种算数变量,把short值赋值给long类型的变量不会改变这个值,只会占用更多的字节,而把一个很大的long值赋值给一个flota变量时,则可能导致这个值的精度降低,因为float只有6位有效数字。下面是一些例子
#include <iostream>

int main(void)
{
	using namespace std;
	cout.setf(ios_base::fixed,ios_base::floatfield);
	float tree=3;
	int guess(3.9881);
	int debt=7.2E12;
	cout<<"tree = "<<tree<<endl;
	cout<<"guess = "<<guess<<endl;
	cout<<"debt = "<<debt<<endl;
	return 0;
}
以下是答案:

不难看出把int值3赋值给float时,发生自动转换变为3.00000再赋值给tree变量,而把一个double值赋值给int变量guess时发生截断(C++选择向0取整),所以guess的值为3,而int变量的最大值无法存储7.2E12,所以这个结果没有定义,在我的系统上显示如上的值。
在C++11标准中,通过大括号初始值时,对类型的转换要求更严格,不允许缩窄,也就是说不允许把范围大的类型赋值给范围小的类型。比如不能把浮点类型转换为整型,而整型之间的转换是允许的,整型到浮点型的转换也是允许的。
int x=66;
char ch1 {231231};//不允许,char 无法容纳231231
char ch2 ={4};//允许
char ch3 {x};//不允许

其中有意思的应该是不能把x赋值给ch3变量,虽然x的值为66,char类型能够容纳这个值,但就编译器看来,x不是常量,它是个变量,所以它有可能是个很大的值,因此不允许这样初始化。

2.1.2表达式中包含不同的类型时,C++将对值进行转换

考虑以下的几行代码会发生什么?
short s1=23;
short s2=11;
short s3=s1+s2;
也许你会认为就是把2个short变量相加再赋值给另外一个short变量这么简单而已。可实际发生的情况是先把这两个short变量转换为int类型,然后相加,将相加的结果再转换为short类型赋值给s3。可能看起来觉得很奇怪,不可思议,但是实际上计算机就是这么做的,意味着计算机使用int时会获得最快的运算速度,因此是最自然的类型。通常在不同类型的值进行算数运算时,编译器会通过如下的校验表选择进行转换,这是最新的C++11校验表,和以前的略有不同。
(1)如果有一个操作数是long double,则把另外一个操作数转换为long double。
(2)否则。如果如果有一个操作数是double,则把另外一个操作数转换为double。
(3)否则。如果如果有一个操作数是float,则把另外一个操作数转换为float。
(4)否则。说明操作数都是整型,执行整型提升。
(5)如果两个操作数都是无符号或者有符号的,且一个操作数的级别比另外一个操作数级别低,则把级别低的操作数转换为级别高的类型。
(6)如果一个操作数是有符号类型,一个操作数是无符号类型的,且无符号类型的操作数级别更高,则把有符号类型的操作数转换为无符号类型的
(7)否则,如果有符号类型可以表示无符号类型的所有取值,则把无符号类型转换为有符号类型的。
(8)否则,把两个操作数转换为有符号类型的无符号版本。
看起来可能有点复杂,其实就是根据类型级别的高地进行转换而已。

2.1.3将参数传递给函数时,C++将对值进行转换

传递参数时的类型通常由函数原型控制。然而也可以取消原型对参数传递的控制,这种情况下C++将char和short应用整型提升。为了与传统C语言的代码保持兼容,一般把float参数提升为double。

2.2强制类型转换

上面提到了C++中发生的自动转换,自动转换由编译器帮我们完成,而如果我们想short转换为char类型而不是int类型时该怎么办呢?这就需要强制类型转换了。
强制类型转换有以下几种形式:
(typeName) value    (long) ssy; //来自传统的C语言格式
typeName (value)    long(ssy); //来自C++格式
C语言风格把需要转换的目的类型用()括起来,而C++风格则把转换看成函数调用的形式,另外C++中还单独引入了4个类型转换运算符,其中static_cast<>可以把一种数值类型转换为另外一种数值类型
它的形式如下:
static_cast<typeName> (value)
几种转换形式如下:
#include <iostream>
</pre></div><div><span style="font-size:18px"><span style="font-size:18px"><span style="font-size:18px"></span></span></span><pre name="code" class="cpp">int main(void)
{
	using namespace std;
</pre></div><div><span style="font-size:18px"><span style="font-size:18px"><span style="font-size:18px"></span></span></span><pre name="code" class="cpp">	int x=2;
	int y,z;
	y=(int)12.1 +(int)23.1;
	z=int(11.1)+int(31.1);
	short s=static_cast<short> (x);
	return 0;
}

2.3C++11中的auto

除此之外,在C++11中新增了一个关键字auto,通过它定义变量则可以根据被赋予的初始值自动定义变量的类型。
auto x=2; //x是int变量
auto y=3.1; //y是double变量
</pre></div><div><span style="font-size:18px"><span style="font-size:18px"><span style="font-size:18px"><span style="white-space:pre"></span></span></span></span><pre name="code" class="cpp">//如果想把abc都指定为double变量,则auto可能用错
auto a=0.0; //a是double变量
double b=0; //b是double变量
auto c=0;  //c是int变量
</pre><pre name="code" class="cpp">
<span style="white-space:pre">	</span>对于简单类型可能auto并不能体现太大优势,而涉及到STL时,比如定义了vector<string>::const_reverse_iterator s_iter=s.rbegin();时如果使用
auto s_iter=s.rbegin();则可以方面很多
</pre><pre name="code" class="cpp"><span style="white-space:pre">	</span>总的说来,C++中的类型转换并不是特别复杂,除了我们强制转换外,只需要清楚每种类型转换的优先级,就能比较容易的知道转换是如何完成的了。

猜你喜欢

转载自blog.csdn.net/Sylvernass/article/details/44836449
今日推荐