本节书摘来自华章社区《C语言程序设计:问题与求解方法》一书中的第3章,第3.8节不同类型数据之间的类型转换,作者:何 勤,更多章节内容可以访问云栖社区“华章社区”公众号查看

3.8 不同类型数据之间的类型转换
机器语言的算术运算指令比C语言算术表达式的限制更多。为了让计算机执行机器指令中的算术运算,通常不仅要求两个操作数有相同的长度(字节数),而且还要求数据的存储方式也相同。比如同是单精度浮点型数。
在C语言中,最好把同类型的常量值赋给同一类型的变量,或者使用同类型的常量和变量进行算术运算或关系运算。
然而在C语言程序中,允许在表达式中混合使用各种不同类型的数据。在一个表达式中,可以同时出现整型、浮点型、字符型的常量和变量。在这种情况下,C语言编译程序通常需要生成一些附加的指令,在执行一条运算类指令之前,将其中一个操作数的类型转换成另一个操作数的类型。
下面讨论的类型转换都是有符号型的变量和常量之间的类型转换,不涉及无符号的变量(和常量)。这适用于常规的编程应用范围。一些高级语言(比如Java语言),就只有有符号型的常量和变量。
类型转换分为自动类型转换和强制类型转换两种。自动类型转换指的是编译器在将语句(或表达时)翻译成指令时,由编译程序自动进行的类型转换。在以下四种情况中会出现自动类型转换:
1)二元算术运算符或关系运算符两边的操作数类型不一致。
2)赋值运算符两边的操作数类型不一致。
3)函数调用时实际参数与形式参数要求的类型不一致。
4)函数调用结束时返回值的类型与要求的类型不一致。
其中,第3种和第4种类型转换讨论,请参见第7章。
本章以下仅讨论前两种情况下的自动类型转换。
(1)算术或关系表达式中的类型转换
在算术(或者关系)表达式中,出现在二元运算符两侧的运算量可以是不同类型的,这时就涉及类型之间的转换问题。如果没有出现强制类型转换,那么简单的自动类型转换规则分为三种:
1)只要两个操作数中出现了char类型或 short 型,首先都将无条件地自动提升为int型。
2)在两个操作数的类型都不是浮点型的情况下,自动进行了第一种规定的无条件的类型提升之后,按照以下方式对操作数的类型再次进行有条件的提升。这个条件是两个操作数之中有一个数是long型,即将int提升为long型。
举例来说,对于“short n1 ; long num;”,要求计算表达式n1 + num。编译器先将变量 n1自动提升为int型。由于两个操作数中有一个变量num是long型,因此,刚刚提升为int 型的变量n1的值将再次提升为long型。
延伸与拓展:整型类型提升的技术内幕
增加临时存放此数的字节和对这些字节进行符号位的扩展,这是由于计算机是用补码来表示有符号整数的。只有对补码进行符号位的扩展,补码表示的值才不会改变。参见本章提高部分有关补码的讨论。
3)两个操作数都是浮点数或者其中有一个是浮点数的情况下,提升规则如下:
long double (这是C99标准规定的类型)

double

float
也就是说:
如果在一个表达式(或一个二元算数或关系运算符)中出现了long double 型的运算量,则此表达式计算出的最终值是long double型的。
如果一个表达式(或一个二元算数或关系运算符)中出现了double 型的运算量(但没有出现long double型量),则此表达式计算出的最终值是double型的。
如果一个表达式(或一个二元算数或关系运算符)中出现了float 型的运算量(但没有出现double型量或long double型量),则此表达式计算出的最终值是float型的。
如果两个操作数中还有一个int型或 long 型的整型量,那么此整型数就会根据另一个浮点操作数的类型进行转换。
读者还要注意的是:数据类型的转换,并不是在计算表达式的值之前一次性完成的,而是根据规定的运算顺序,逐步进行类型转换的。例如,对于如下表达式:
56.91+'A'*32
是先按照转换规则,将char型的量'A'转变为int型值(第一种类型提升)进行乘法运算;得到一个整数值以后,再按照转换规则转变成double型(这是由于前一个参与运算的常量59.61被系统默认为double型常量),然后再与56.91进行双精度浮点数加法运算。
(2)赋值语句(或赋值表达式)中的类型转换
在赋值语句(或赋值表达式)中,如果赋值运算符右边表达式计算结果的类型与左边变量的类型不一致,则会自动进行类型转换。类型转换的规则很简单:将表达式计算出的值转变成赋值号左边变量的类型。
如果赋值号右边的数据类型的取值范围宽于左边变量类型的取值范围,通常会发生精度的额外丢失或者错误。
例如,如果定义“char d_char ; int d_int ; float d_float ; double d_double ;”,那么以下赋值语句(或赋值表达式)是不会有任何问题的,因为右边的数据类型“不宽于”左边变量类型的取值范围。
d_int = d_char;
d_float = d_int;
d_double = d_float;
但是,如果将以上几条赋值语句(或赋值表达式)中的变量调换位置:
d_char= d_int;
d_int =d_float;
d_float= d_double;
通常都会出现问题。
对于第1条语句“d_char= d_int;”,在d_int的值超过255时,在char只占8位内存的计算机上必然出错(溢出)。即使d_int的取值在128~255之间,也不一定正确。这要看你正在使用的C编译器中,char类型本质上到底是有符号的整数(取值在–128~127之间)还是无符号的整数(取值在0~255之间)。如果是前者,就会出现把一个正整数变成了一个负整数并且存放到变量d_char中的错误。
对于第2条语句“d_int =d_float;”,必然会使d_float的小数部分丢失(不会四舍五入)。更为严重的是,如果d_float的值超出了int类型的取值范围(这或许是很常见的,因为有些C编译器中,int型的最大值是32767),那么变量d_int中的值也必然出错(溢出)。
第3条语句的情况,读者可自行分析。
(3)强制类型转换
如果自动类型转换满足不了需要,则可以要求编译程序进行强制类型转换。强制类型转换是通过使用强制类型转换运算符(由圆括号括住类型名构成)来实现的。其格式为:
(类型名)(被转换的表达式)
其功能是把表达式的运算结果,强制转换成类型名所给定的类型。例如,(float) m 把整型变量m的值强制转换为单精度浮点型。(int)(3.86x–y)把表达式3.86x–y的值强制转换为整型。
在进行强制类型转换时应注意:类型名必须用圆括号括住,不能省略;需进行类型转换的表达式也要加圆括号(单个变量或常量可以不加括号)。例如,如果错把(int)(x–y)写成(int)x–y,则会出现仅仅把x转换成int类型之后,再与y相加的问题。
以下两种情况下要使用强制类型转换:
1)如果担心两个float型量x,y的乘积超出float型的表示范围(即产生溢出),那就要这样书写语句:z=(double )xy;。其中,变量z是double类型,y的类型会自动提升为double型。注意,另一个很类似的语句:z=(double )(xy);是错误的,因为在进行强制类型转换前,x*y的乘积值很可能已经超出了float型的表示范围。
2)如果担心两个int型量i,j的乘积超出int型的表示范围,那就要这样书写语句: k=(long int )i*j;,其中k是long int类型的变量。
强制类型转换如果使用不当,出现的问题与赋值语句中自动类型转换的类似。
注意:无论是强制类型转换或是自动类型转换,都只是为了本次运算的需要而对从变量中取出的值进行的临时性转换,不会改变变量定义时对该变量指定的类型,也不会改变变量所对应内存单元中存放的值。
无符号的变量(和常量)之间的类型转换,与本节讨论的情况完全类似。强烈建议读者在通常应用中不要在表达式中使用无符号的常量与变量。无符号的常量和变量最好局限于应用在系统编程和嵌入式编程方面。所以,读者应尽量避免在同一个表达式中,同时使用有符号和无符号的量。无符号与有符号量之间的类型转换的讨论,请读者参考相关的教科书。

《C语言程序设计:问题与求解方法》——3.8节不同类型数据之间的类型转换相关推荐

  1. python怎么分析数据差异的方法_如何比较两组数据之间的差异性

    展开全部 1, 首先,分别把这两组数据分别设为x和y,打开SPSS,点击左下角的Variable  View选项卡,e5a48de588b6323131333532363134313032313635 ...

  2. python语言程序设计——蒙特·卡罗方法求圆周率

    虽然在python的math库中存在着圆周率的表示,但是在实际生活中又有谁可以完整的背出圆周率呢,圆周率又是怎样被计算出来的呢? 首先数学家们发现了圆周率的近似方程如下: 而这段代码自然可以用计算机中 ...

  3. 月份30或31c语言编程,C语言程序设计上机编程方法.PPT

    C语言程序设计上机编程方法 2000年1月25日 北京理工大学 / <C语言程序设计>上机编程方法 <C语言程序设计>上机编程方法系列讲座 5月24日 中心教学楼0231 下午 ...

  4. C语言程序设计-算数运算符、赋值运算符、逗号运算符及表达式

    目录 1.5 运算符和表达式 1.5.1 算术运算符和表达式 1.5.2 赋值运算符和表达式 1.5.3 逗号运算符和表达式 传送门上一节:C语言程序设计-常量与变量 传送门下一节:C语言程序设计-不 ...

  5. c语言程序设计课程作用,《C语言程序设计》课程标准

    <C语言程序设计>课程标准 适用专业: 三年制中职计算机应用专业 一.前言 (一)课程的性质 本课程是中职软件与信息服务专业的一门主干专业基础课程,旨在培养学生计算机编程基本思想.编程基本 ...

  6. c语言程序设计课件第二章,c语言程序设计课件张元国 ISBN9787566300386 PPT第二章数据类型 运算符与表达式...

    1.第2章 数据类型.运算符与表达式,语言的数据类型 常量与变量 运算符与表达式 不同类型数据间的转换,2.1语言的数据类型,数据是计算机程序处理的所有信息的总称,数值.字符.文本等都是数据,在各种程 ...

  7. c语言程序设计第二版课后答案 机械工业出版社,C语言程序设计 第2版

    图书简介 本书的写作融入了作者多年的教学经验,充分考虑到初学者的能力.认知水平.知识结构等因素,遵照循序渐进.由浅入深的原则,较系统地介绍了C语言程序设计知识.内容涵盖算法及算法设计.数据描述与基本操 ...

  8. c语言中apos是什么头文件,华中科技大学计算机学院C语言程序设计字符串apos;apos;apos;apos;.ppt...

    华中科技大学计算机学院C语言程序设计字符串'''' 第3章 基本的标准输入与输出 华中科技大学计算机学院 C语言程序设计 C语言程序设计 主讲教师:周时阳 标准输入输出是指利用标准C提供的输入输出库函 ...

  9. C语言程序设计——实验教学大纲

    课程信息 课程名称:C语言 实验学时:24学时 实验室名称:现代教育技术实验中心 实验课性质:非独立设课 适用专业:教育技术学 一.实验教学目的 掌握C语言的基本知识和程序设计方法: 培养计算机程序设 ...

最新文章

  1. Django博客系统(404页面展示)
  2. php 数组值的交集,PHP 数组交集与差集
  3. 《Adobe Flash Professional CC经典教程》——1.13 查找关于使用Flash的资源
  4. SpringMVC环境配置全过程IntelliJ IDEA 2020.3.1
  5. linux fdisk 磁盘空间使用率,linux查看磁盘剩余空间以及cpu使用情况
  6. python爬虫开发数据库设计入门经典_Python3实现的爬虫爬取数据并存入mysql数据库操作示例...
  7. 【华为云实战开发】8.如何快速搭建C#网站并实现持续集成?
  8. SmartUpload 中文API帮助
  9. 华为在 5G 初期不考虑盈利;​网易发布数据中台;微软 SQL Server 2019 免费支持 Java | 极客头条...
  10. ArcEngine在个人地理数据库下创建要素类
  11. git fetch实战以及与git pull 的区别
  12. 图论最短路问题和最小生成树问题的区别
  13. Bat批处理命令执行中文路径解决方法
  14. android根据轮播图片颜色改变背景颜色
  15. 阿里天池大数据竞赛——口碑商家客流量预测 A
  16. Multiprocessing 学会多进程 (莫烦 Python 教程)笔记-4-进程池pool
  17. runtime error python 3.5_Python 3.5 RuntimeError: can't start new thread
  18. android sdk manager 快速下载sdk
  19. 微信公众号教程(3)微信公众平台群发消息
  20. 最实用的自用同花顺主力资金暴发进出公式

热门文章

  1. Linuxshell之高级Shell脚本编程-创建函数
  2. python-- Image 模块
  3. EffectiveC++ Item11
  4. 一年春事,桃花红了谁……
  5. Silverlight:如何在程序中获取网站的根目录
  6. Java虚拟机性能监控与调优实战
  7. 前端之Bootstrap框架
  8. BZOJ1833:[ZJOI2010]数字计数——题解
  9. 鼠标点击实现划掉文字效果
  10. MySQL 错误1418