《C++程序设计教程(第3版)》——第2章,第5节类型转换

简介:

本节书摘来自华章出版社《C++程序设计教程(第3版)》一书中的第2章,第2.5节类型转换,作者张志航,更多章节内容可以访问云栖社区“华章计算机”公众号查看

2.5 类型转换
2.5.1 赋值时的自动类型转换
如果赋值运算符两侧的类型不一致,则遵循以下几条原则进行类型转换后赋值。
1.实型量赋给整型变量
实型量赋给整型变量时,简单舍弃小数部分,将实型量的整数部分赋给整型变量,不进行四舍五入。如“int i=3.96;”,则i被赋值为3。
2.整型量赋给实型变量
整型量赋给实型变量时,数值不变,有效数字位数增加。例如,若有“float f=23;”,则f获得的值为23.0,以单精度浮点格式存储,具有6~7位有效数字;若有“double d=23;”,则d获得的值为23.0,以双精度浮点格式存储,具有15~16位有效数字。
3.整型量之间相互赋值
整型量有8种,它们分别是[signed] char、unsigned char、[signed] short、unsigned short、[signed] int、unsigned int、[signed] long、unsigned long。此处将char型量看作1字节长度的整型量。各种类型的整型量占用的字节数是不同的,按照其二进制位数的多少,区分为“长的”整型量和“短的”整型量。所谓“长的”整型量是指该整型量的二进制位数较多,所谓“短的”整型量是指该整型量的二进制位数较少。整型量之间相互赋值,系统处理为它们内存数据之间的赋值,分两种情况。
(1)“长的”整型量赋给“短的”整型量
将“长的”整型量赋给“短的”整型量时,方法是“低位截断”,将“长的”整型量的高位去掉,截取其与“短的”整型量相同位数的低位二进制位,然后进行赋值。例如,“char c=250;”将int型常量250赋给字符型变量c。250为int整型常量,在内存中的存储形式是32位二进制数 0000 0000 0000 0000 0000 0000 1111 1010。变量c是8位有符号二进制整型量,赋值原则是取250内存数据的低8位赋给c,此时c中的值是1111 1010。C++中整型量是以补码形式存放的,因此,变量c的真值是-6。
又如,“short int a=65 536;”将常量65 536赋值给变量a。常量65 536是int型量(其值是216),在内存中的存储形式是:0000 0000 0000 0001 0000 0000 0000 0000。短整型变量a在内存占16个二进制位,赋值时截取65 536内存中的低16位赋给a,此时a的16个二进制位全为0,则a的值是0,这称为赋值溢出。因为65 536超过了短整型量的数值范围(-32 768~32 767),无法直接赋值给短整型量。
(2)“短的”整型量赋给“长的”整型量
“短的”整型量赋给“长的”整型量又分成两种情况。
1)将“短的”无符号整型量赋给“长的”整型变量,方法是在“短”的无符号整型量前补0,使其长度达到“长的”整型量的位数。例如:
unsigned char c = -4;
int i;
i = c;
此例中涉及两次赋值,赋值过程中各常量、变量的内存形式如下。首先将“长的”整型量-4赋给“短的”整型变量c,c获取的值是-4的内存表示形式的低8位;再将“短的”c变量的值赋给“长的”整型变量i。因为c是无符号整型量,占8位,而i是32位,此时在c的内存内容前补0使其扩展到32位后,赋值给变量i。
-4:1111 1111 1111 1111 1111 1111 1111 1100
c: 1111 1100
i:0000 0000 0000 0000 0000 0000 1111 1100
结果:变量i的值是252。
2)将“短的”有符号整型量赋给“长的”整型量。此种情况只需做符号位扩展,即在“短的”整型量前补符号位,使其长度达到“长的”整型量的长度,然后赋值。例如:
char c = -4;
int i = c;
赋值过程中各常量、变量的内存表示形式如下:
-4:1111 1111 1111 1111 1111 1111 1111 1100
c: 1111 1100
i:1111 1111 1111 1111 1111 1111 1111 1100(扩展负号)
结果:变量i的值是-4。又如:
char c = 4;
int i = c;
赋值过程中各常量、变量的内存表示形式如下:
4:0000 0000 0000 0000 0000 0000 0000 0100
c: 0000 0100
i:0000 0000 0000 0000 0000 0000 0000 0100(扩展正号)
结果:变量i的值是4。

2.5.2 各种类型运算量混合运算时的自动类型转换
C++语言中各种类型的常量和变量之间可以混合运算。例如,已知“int a=1; double b=2;”,则可进行a+b运算。两个不同类型的量运算时,计算机内部首先将它们转换成相同数据类型的量,然后进行运算。例如,上述a+b运算,计算机首先将a的值转换为double型表示,然后与double型的b的值相加。这种转换是C++内部自动完成的,编程者必须掌握转换规则,否则编程会出问题。转换规则如图2-4所示。图2-4中横向向左的箭头表示必定转换。例如,已知“char c1, c2;”,在做c1+c2运算时,首先将c1和c2的值均转换成int型表示,再将两个int型量相加。图2-4中纵向箭头表示不同数据类型混合运算时的转换方向,规则是由低类型向高类型转换,例如,上述a+b运算将低类型int值转换成高类型double值,然后运算。所谓低类型是指占用存储字节少、数据范围小的类型,所谓高类型是指占用存储字节多、数据范围大的类型。
例如,已知“int i; float f; double d;”,则表达式10+'a'+i * f - d / i的运算顺序和类型转换过程如图2-5所示。首先计算第①步,结果是int型量,再依次计算第②~⑤步,最终整个表达式的结果的类型是double型。


41de98658973c71fe1a8a329e6bc98cbbb65cd06


2ac4404ecd5761e403acc34b56d3f068b2de68d1

掌握了混合运算时数据类型的转换规则后,读者应该能理解5/2的结果为2,5.0/2的结果为2.5的道理了,参见2.4.2节。

2.5.3 强制类型转换
前面介绍了不同类型量相互赋值时以及混合运算时的自动类型转换,但有时为了强调类型的概念或者为了满足运算符对数据类型的要求,可以显式地写出类型转换,称为强制类型转换。格式是:
<类型名> (<表达式>) 或 (<类型名>) <表达式>
例如:
`int i, a;
float x, y;
double z;
i = int(x+y); 或 i = (int)(x+y);
z = double(a); 或 z = (double)a;
a = int(z) % i; 或 a = (int)z % i;`
例如,i=int (x+y)的意义是将表达式x+y的值转换为int型量,赋值给变量i。类型转换运算符的优先级较高,表达式int (z) % i中运算符int优先级较高,所以首先计算int (z),即将z的值取整,再进行%运算。注意,%运算符要求运算量为整型量,必须首先将z的值强制转换为整型量,才能计算%运算符。
注意:类型强制转换的对象是表达式的值,表达式double (a)的意义是将a的值(即表达式的值)转换成double型,而变量a自身仍然是int型变量。

相关文章
|
21天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
55 5
|
2月前
|
算法 数据挖掘 Shell
「毅硕|生信教程」 micromamba:mamba的C++实现,超越conda
还在为生信软件的安装配置而烦恼?micromamba(micromamba是mamba包管理器的小型版本,采用C++实现,具有mamba的核心功能,且体积更小,可以脱离conda独立运行,更易于部署)帮你解决!
70 1
|
2月前
|
存储 C++
c++的指针完整教程
本文提供了一个全面的C++指针教程,包括指针的声明与初始化、访问指针指向的值、指针运算、指针与函数的关系、动态内存分配,以及不同类型指针(如一级指针、二级指针、整型指针、字符指针、数组指针、函数指针、成员指针、void指针)的介绍,还提到了不同位数机器上指针大小的差异。
55 1
|
2月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
20 1
|
2月前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
36 3
|
2月前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
48 3
|
2月前
|
Linux C语言 C++
vsCode远程执行c和c++代码并操控linux服务器完整教程
这篇文章提供了一个完整的教程,介绍如何在Visual Studio Code中配置和使用插件来远程执行C和C++代码,并操控Linux服务器,包括安装VSCode、安装插件、配置插件、配置编译工具、升级glibc和编写代码进行调试的步骤。
321 0
vsCode远程执行c和c++代码并操控linux服务器完整教程
|
2月前
|
C++
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
21 0
|
6月前
|
安全 C++
C++:程序设计实例
C++:程序设计实例
54 2
|
5月前
|
存储 安全 编译器
【C++11】类型转换
【C++11】类型转换
32 0