数据类型转换的方式

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)——类型转换的本质与处理的更多相关文章

  1. C语言提高 (1) 第一天 数据类型本质与内存四区

    (物联网的分层的概念 b/s c/s 结构 习惯: 在C语言 0 函数执行成功 <0是错误 >1做一些返回值处理 3 课前准备 工作经验,记录 4 数据类型的本质 数据类型的本质是固定大小 ...

  2. C语言中动态内存分配的本质是什么?

    摘要:C语言中比较重要的就是指针,它可以用来链表操作,谈到链表,很多时候为此分配内存采用动态分配而不是静态分配. 本文分享自华为云社区<[云驻共创]C语言中动态内存分配的本质>,作者: G ...

  3. 李洪强漫谈iOS开发[C语言-002]-开发概述程序的本质与简单执行过程

    李洪强iOS开发之应用程序的本质与简单执行过程 什么叫程序? 就是一段执行指令 程序的两个状态: 保存状态(保存到硬盘上)   运行状态(由CPU执行) 代码可以执行吗? CPU(中央处理器-> ...

  4. C语言的本质(31)——C语言与汇编之函数调用的本质

    我们一段代码来研究函数调用的过程.首先我们写一段简单的小程序: int sum(int c, int d) { inte = c + d; returne; } int func(int a, int ...

  5. C语言中强制数据类型转换(转)

    原文地址不详 字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128-127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围是0-255(有些 ...

  6. C语言-逃逸字符、类型转换和布尔类型

    C语言-逃逸字符 逃逸字符是用来表达无法印出来的控制字符或者特殊字符,它由一个反斜杠""开头,后面跟上另一个字符,这两个字符合起来,组成一个字符. \b是backspace,在su ...

  7. Java | this的本质 和 static的本质

    this 在说this之前先说一下,对象创建的过程: 1.分配对象空间,并将对象成员变量初始化. 2.执行属性值的显式初始化. 3.执行构造方法. 4.返回相关的地址给相关的对象.   this的本质 ...

  8. C语言隐式强制类型转换

    今天又被精度问题困扰,把最基本的东西忘了. int n = 5; int cnt = 5.5; double sum = (n-cnt);  运算完后sum是 -0.5.不知道什么时候n转换成doub ...

  9. C语言系列之强制类型转换(一)

    例子: #include <stdio.h> { char cChar;   //字符型变量 short int iShort; //短整型变量 int ilnt;           / ...

随机推荐

  1. Ubuntu 14.04卸载安装失败的Mysql数据库,以及重新安装配置

    一.删除原来Mysql 1.删除mysql的数据文件 sudo rm /var/lib/mysql/ -R 2.删除mqsql的配置文件 sudo rm /etc/mysql/ -R 3.自动卸载my ...

  2. WeUI

    从WeUI学习到的知识点   WeUI是微信Web服务开发的UI套件, 目前包含12个模块 (Button, Cell, Toast, Dialog, Progress, Msg, Article, ...

  3. 正式学习 react(三)

    有了基础的webpack基础,我们要对react的基本语法进行学习. 我这个教程全部用es6 实现.可能会忽略一些最基本的语法讲解,这些你在官网上或者其他别的地方都比我讲的全. 今天我要讲一下reac ...

  4. MFC永久窗口对象与临时窗口对象

    这篇讲得很清楚,就转过来了,原文如下: 因项目需要,最近在学习MFC,下午在一篇教程中提到了临时窗口.永久窗口,作者让读者自行查阅MSDN,了解临时窗口与永久窗口的概念,出于好奇,出于方便,直接百度一 ...

  5. MongoDB 分片操作

    添加分片 use admin //添加分片节点,每个分片都是一个副本集[allowLocal:true仅仅开发时才将分片配置到本地,生产时不能这样] db.runCommand({addshard:& ...

  6. Linux(gnu)环境动态链接库的搜索路径

    摘自http://blog.csdn.net/saga1979/article/details/14161229 man ld.so(8)说,如果库依赖不包括“/”,那么它将按照下面的规则按顺序搜索: ...

  7. mysql 1449 : The user specified as a definer ('montor'@'%') does not exist

    grant all privileges on *.* to root@"%" identified by "."; flush privileges;  

  8. 格而知之2:UIView的autoresizingMask属性探究

    UIView的autoresizingMask属性,是用在当一个UIView实例的父控件的尺寸发生变化时,来自动调整UIView实例在父控件中的位置与尺寸的.autoresizingMask属性是一个 ...

  9. Chessboard(规律)&&阿里巴巴和n个大盗(规律)

    Chessboard Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  10. Longtail Hedgehog(DP)

    Longtail Hedgehog time limit per test 3 seconds memory limit per test 256 megabytes input standard i ...