C语言的本质(5)——类型转换的本质与处理
数据类型转换的方式
C 语言中的数据类型转换可分为隐式转换和显式转换两种。
隐式转换
隐式转换也可称作为自动转换,它经常以以下几种形式发生:
1、在计算一个同时出现多种数据类型的表达式时,将所有数据类型都转换为同一种数据类型。
2、在对数据进行输出时,按指定格式将数据输出。
3、利用赋值运算符将数据转换为运算符左边指定的数据类型。
4、在对函数调用时,如果形参与实参的数据类型不一致,实参会自动转换为形参的数据类型。
根据转换发生的形式,可将隐式转换分为类型:一般算术转换、输出转换、赋值转换与函数调用转换。
一般算术转换
这种转换类型会经常出现,它是通过编译器自动实现的,不同类型的数据在一个表达式中会自动转换为最长的类型,例如:
有如下定义char a; int b,e; float c; double d;
计算a*b+c-d/e 时,按计算顺序说明类型转换:
1、 a*b; // char 类型的a 转换为int 类型的值, 再和int 类型的b 相乘。
2、d/e; // int 类型的e 转换为double 类型的值,然后double类型的d 再和e 相除。
3、a*b+c; // int 类型的a*b 转换为float 类型值,再和float 类型的c 相加。
4、a*b+c-d/e; // float 类型的(a*b+c)转换为double 类型的值,再和double类型的d/e 相减。
不考虑过程,最终表达式的值为最长类型(这里是double)的值。
格式输出转换
这种转换类型是将某种类型的数据按照输出格式转换成指定格式。例如:
main(){int a=65;printf("%c\n",a);} //输出“A”
此程序是将ASCII 值为65 的字符输出来,所以输出结果是“A”。
赋值转换
在这种转换中,会出现赋值运算符“=”,就是要将运算符右边的数据类型转换为运算符左边的数据类型,例如:
int main()
{
inta=3.15;
printf("%d\n",a);
} //输出结果是3
之所以会出现这种结果,就是因为运算符右边的3.15 是浮点型常量,它要被转换为运算符左边的整型数据,导致整型变量被赋
值为3。
函数调用转换
此种类型的转换主要会出现在函数调用时形参跟实参数据类型发生不一致的场合,例如:
int mul(int x,int y) //函数中的形参为int
{
int a;a=x*y;
return(a);
}
int main()
{
float a=1.23,b=2.35;
int c;c=mul(a,b); //调用函数时,由于实参是float,所以实参首先会转换为int,再执行函数体部分
printf("%d",c);
} //输出结果是2
显式转换
显式转换可分为两种,即强制性数据类型转换以及利用标准函数转换。
强制性数据类型转换
强制性数据类型转换是将某一种数据类型强制转换为另外一种数据类型。这一种较常见。强制性数据类型转换的一般格式为:
(类型标识符)表达式
例如:
int main()
{
float a=5.6,b=2.3;
printf("%d\n",(int)a%(int)b);
}
由于运算符“%”要求两个数据必须为int 类型,如果不进行强制性数据类型转换,则系统会提示出错信息,所以浮点型数据a 和
b 先各自转换为整型数据5 和6,再进行求余运算,输出结果是1。
标准函数转换
这种转换是利用C 语言中的标准函数将某一种数据类型转换为另外一种数据类型。例如:
int main(void)
{
int a; float b ; char*c="123.45xy", *d;
b=atof(c); //将字符串c 转换为float 型数据
a=atoi(c); //将字符串c 转换为int 型数据
itoa(a,d,10); //将十进制数a 转换为字符串数据并且存放在字符型指针d 所指向的字符串
printf("%.4f,%d,%s\n",b,a,d); //将浮点型数据b、整型数据a 以及字符串数据d 分别按照浮点型、十进制数整型和字符串格式
输出,输出结果是:123.4500,123,123
}
常见问题
在对数据类型进行转换时,是为了程序的需要,可有的时候却会带来意想不到的安全隐患和错误,这就是非安全转换、输入输
出格式错误与运算符数据不匹配。
1、非安全转换
非安全转换是将一种数据类型长的转换成其它数据类型短的数据,使其值的表示范围被缩小所出现的错误。它有如下几种情
况:
较大整数转换为较短的类型
C 语言系统一般不检测这种类型的错误,大部分的编译器在可能出现非安全转换是不会给出警告信息,因此在编程时需避免此
类型转换。
如
int main()
{
long i=123456;
printf("%d\n",i);
} //其输出结果为-6716.
又如
int main(){
unsigned i=65535;
int j ;
j=i;
printf("%d\n",j)
}//输出结果为-1.
有符号负数转换为无符号数
例如:
int main()
{
int i=-1;
printf("%u",i);
} //其结果为65535
当由有符号数转换为无符号数时,原来的符号位将不作为符号,而作为数据的一部分。
双精度类型转换为单精度类型
例如:
int main()
{
double i=10.123456789;
float j=i;
printf("%.9f\n",j);
} //输出为10.123456955
int main()
{
double i=12345678912345.123;
float j=i;
printf("%f\n",j);
} //输出为12345679020032.000000
由于双精度类型转换成单精度类型时,可能出现以下两种情况:其一,降低精度,截断尾数,保留前8 位有效数字,后面的数字
无意义,如例1;其二,若数值超出了单精度所表示的范围,则得到的数据无意义,且系统不提示错误,因此在遇到较大的数据,或对
数据精度要求比较高时,应避免进行此类的转换。
浮点数转换为整型
当浮点数转换成整型数据时,舍弃小数,不进行四舍五入,例如:
int main()
{
double i=15.99999;
int j=i;
printf("%d\n",j);
} //其输出为15
因此,若需要计算结果尽可能高的精度,应避免此种类型的转换。
2、输入输出格式错误
这种错误会出现在格式输入与格式输出函数中。例如:
int main()
{
int i=2;
printf("%f",i);
} //会出现编译错误(数据类型不一致)
3、算术运算“/”、“%”与数据类型不匹配
例如:
int main( )
{
int i=7,j=2;
printf("%d\n",i/j);
} //输出结果为3
程序的本来目的是想得到结果3.5,可是结果却是3,,是因为变量i 和j 都是int 类型的,其结果也是int 类型的,如果
想得到3.5 的话,就要将i 和j 都要强制转换为float 类型;
int main( )
{
float i=12.45,j=6.3;
printf("%d\n",i%j);
} //提示错误: 非法地使用浮点数在main函数中
之所以会出现系统提示错误,是因为运算符“%”左右两侧的数
据类型都必须是int,但程序中两个变量却都不是int 类型的,因此,想让系统不出错误,就必须将两个变量都强制转换为float 类型。
从上述两个例子来看,对于算术运算符“/”和“%”,一定要注意数据类型的匹配。
在C 语言中,多种数据类型之间的转换有它出现的必然性,也就是在某些情况下,数据转换是必须的,但应尽量避免出现将数
据长的类型转换为数据短的类型、输入输出格式上的错误以及运算符数据类型不匹配等问题。
C语言的本质(5)——类型转换的本质与处理的更多相关文章
- C语言提高 (1) 第一天 数据类型本质与内存四区
(物联网的分层的概念 b/s c/s 结构 习惯: 在C语言 0 函数执行成功 <0是错误 >1做一些返回值处理 3 课前准备 工作经验,记录 4 数据类型的本质 数据类型的本质是固定大小 ...
- C语言中动态内存分配的本质是什么?
摘要:C语言中比较重要的就是指针,它可以用来链表操作,谈到链表,很多时候为此分配内存采用动态分配而不是静态分配. 本文分享自华为云社区<[云驻共创]C语言中动态内存分配的本质>,作者: G ...
- 李洪强漫谈iOS开发[C语言-002]-开发概述程序的本质与简单执行过程
李洪强iOS开发之应用程序的本质与简单执行过程 什么叫程序? 就是一段执行指令 程序的两个状态: 保存状态(保存到硬盘上) 运行状态(由CPU执行) 代码可以执行吗? CPU(中央处理器-> ...
- C语言的本质(31)——C语言与汇编之函数调用的本质
我们一段代码来研究函数调用的过程.首先我们写一段简单的小程序: int sum(int c, int d) { inte = c + d; returne; } int func(int a, int ...
- C语言中强制数据类型转换(转)
原文地址不详 字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128-127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围是0-255(有些 ...
- C语言-逃逸字符、类型转换和布尔类型
C语言-逃逸字符 逃逸字符是用来表达无法印出来的控制字符或者特殊字符,它由一个反斜杠""开头,后面跟上另一个字符,这两个字符合起来,组成一个字符. \b是backspace,在su ...
- Java | this的本质 和 static的本质
this 在说this之前先说一下,对象创建的过程: 1.分配对象空间,并将对象成员变量初始化. 2.执行属性值的显式初始化. 3.执行构造方法. 4.返回相关的地址给相关的对象. this的本质 ...
- C语言隐式强制类型转换
今天又被精度问题困扰,把最基本的东西忘了. int n = 5; int cnt = 5.5; double sum = (n-cnt); 运算完后sum是 -0.5.不知道什么时候n转换成doub ...
- C语言系列之强制类型转换(一)
例子: #include <stdio.h> { char cChar; //字符型变量 short int iShort; //短整型变量 int ilnt; / ...
随机推荐
- python 源代码分析之调试设置
首先在官方下载源代码,我下载的是最新版本3.4.3版本:https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tgz 解压后的目录如下(借用网上的目 ...
- PHP中的单例模式
额,只是复习到这里,做点笔记吧. 单例模式.何谓也?我想就是唯一吧.唯一的意思大概希特勒已经说的很清楚了.就是我也说不明白--把代码贴上来了事. <?php // Single instance ...
- QTableWidget嵌入QpushButton后定位QpushButton
问题: 有时候会遇到这样的情况,在QTableWidget中我们需要嵌入一个QpushButton按钮,但是如何确定是哪个Button按下的呢? 解决: 一般地,一个按钮按下后会连接到一槽函数,那么在 ...
- Redis存储Session
net Core 使用Redis存储Session 前言 Asp.net Core 改变了之前的封闭,现在开源且开放,下面我们来用Redis存储Session来做一个简单的测试,或者叫做中间件(m ...
- ASP.net(C#)批量上传图片(完整版)
摘自:http://www.biye5u.com/article/netsite/ASPNET/2010/1996.html 这篇关于ASP.Net批量上传图片的文章写得非常好,偶尔在网上看到想转 ...
- 加密芯片ALPU
加密芯片ALPU 纽文微电子(上海)有限公司 n 公司简介 NEOWINE是一家半导体开发公司,2002年6月成立于韩国,于2011年在中国设法人; 研发总部位于韩国京畿道,并在上海.深圳设办事处 ...
- Android 自定义View之BounceProgressBar
之前几天下载了很久没用了的桌面版酷狗来用用的时候,发现其中加载歌曲的等待进度条的效果不错(个人感觉),如下: 然后趁着这周末两天天气较冷,窝在宿舍放下成堆的操作系统作业(目测要抄一节多课的一堆堆文字了 ...
- 4.1. 如何在Windows环境下开发Python
4.1. 如何在Windows环境下开发Python 4.1. 如何在Windows环境下开发Python 4.1.1. Python的最原始的开发方式是什么样的 4.1.1.1. 找个文本编辑器,新 ...
- Linux,Unix各种版本的操作系统在线安装软件命令
摘自:http://blog.csdn.net/zjg555543/article/details/8278266 linux和unix,各个版本的操作系统都有自己的软件安装方式,最方便的莫过于在线安 ...
- Sereja and Coat Rack(水)
Sereja and Coat Rack Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I6 ...