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; / ...
随机推荐
- poj 1940 Wine Trading in Gergovia_贪心
在一条街上有许多房屋,每间屋子里都住着人,并且都是做葡萄酒生意的商人,他们每天都要决定买卖多少瓶葡萄酒.有趣的地方是,供需总是完美地一致.商人总是能买到自己需要的葡萄酒,并且,他们从来不介意是从哪个商 ...
- C编程技巧
1,attempted assighnment to literal if (i == 3) { //codes } else if (4 == 4); 2,引用数组元素相当于对指针加上偏移量的引用 ...
- IOS中http请求使用cookie
http://rainbird.blog.51cto.com/211214/805173 IOS中http请求使用cookie 2012-03-13 23:04:30 标签:http 记录 龙的传人 ...
- 网易云课堂_C++开发入门到精通_章节3: 类、对象和封装
课时12构造函数与析构函数-2 构造函数 构造函数可以有多个 构造函数可以重载 构造函数用于隐式类型转换 class Student { public: explicit Student(int ss ...
- Longest Substring Without Repeating Characters 最长不重复子串
只遍历一次字符串即可求出最长不重复子串的长度. int lengthOfLongestSubstring(string s) { vector<,-); //记录字符上一次出现的位置,ASCII ...
- 链接脚本之LMA VMA解释
链接脚本中的LMA和VMA是什么意思.这个问题纠结了一段时间,今天在看<ARM体系结构与编程>时,豁然开朗,写下自己的认识.分享例如以下: LMA:载入地址 位于存储器中的地址 LOAD ...
- OC中NSString 的常用方法
NSString *str1 = @"BeiJing"; NSString *str2 = @"beijing"; //全部转为大写 NSLog(@" ...
- 《面试题精选》15.O(logn)求Fibonacci数列
题目:定义Fibonacci数列例如以下: / 0 n=0 f(n)= 1 n=1 ...
- DG之主库、备库切换(物理备库)
DG之主库.备库切换 一.开库与关库顺序 开库顺序 先启备库,再启主库(启动监听.打开告警日志) 关库顺序 先关主库,再关备库 二.主备库切换 1.操作过程一览 步骤1:启动备库.监听.告警: 步骤2 ...
- 充分利用HTML标签元素 – 简单的xtyle前端框架
xtyle框架充分利用语义化标签来做美化样式,兼容多款主流浏览器,包括IE8. xtyle框架虽然没BS这么强大,但我觉得也很实用,体积不算很大,适用于企业网站.WordPress主题.个人网站.博客 ...