自动类型转换

自动类型转换就是编译器默默地、隐式地、偷偷地进行的数据类型转换,这种转换不需要程序员干预,会自动发生。

1) 将一种类型的数据赋值给另外一种类型的变量时就会发生自动类型转换,例如:

 float f = ;

100 是 int 类型的数据,需要先转换为 float 类型才能赋值给变量 f。再如:

 int n = f;

f 是 float 类型的数据,需要先转换为 int 类型才能赋值给变量 n。

在赋值运算中,赋值号两边的数据类型不同时,需要把右边表达式的类型转换为左边变量的类型,这可能会导致数据失真,或者精度降低;所以说,自动类型转换并不一定是安全的。对于不安全的类型转换,编译器一般会给出警告。

2) 在不同类型的混合运算中,编译器也会自动地转换数据类型,将参与运算的所有数据先转换为同一种类型,然后再进行计算。转换的规则如下:

      • 转换按数据长度增加的方向进行,以保证数值不失真,或者精度不降低。例如,int 和 long 参与运算时,先把 int 类型的数据转成 long 类型后再进行运算。
      • 所有的浮点运算都是以双精度进行的,即使运算中只有 float 类型,也要先转换为 double 类型,才能进行运算。
      • char 和 short 参与运算时,必须先转换成 int 类型。

     #include<stdio.h>
int main(){
float PI = 3.14159;
int s1, r = ;
double s2;
s1 = r * r * PI;
s2 = r * r * PI;
printf("s1=%d, s2=%f\n", s1, s2);
return ;
}

运行结果:
s1=78, s2=78.539749

在计算表达式r*r*PI时,r 和 PI 都被转换成 double 类型,表达式的结果也是 double 类型。但由于 s1 为整型,所以赋值运算的结果仍为整型,舍去了小数部分,导致数据失真。

强制类型转换

自动类型转换是编译器根据代码的上下文环境自行判断的结果,有时候并不是那么“智能”,不能满足所有的需求。如果需要,程序员也可以自己在代码中明确地提出要进行类型转换,这称为强制类型转换。

自动类型转换是编译器默默地、隐式地进行的一种类型转换,不需要在代码中体现出来;强制类型转换是程序员明确提出的、需要通过特定格式的代码来指明的一种类型转换。换句话说,自动类型转换不需要程序员干预,强制类型转换必须有程序员干预。

强制类型转换的格式为:

(type_name) expression

type_name为新类型名称,expression为表达式。例如:

     (float) a;  //将变量 a 转换为 float 类型
(int)(x+y); //把表达式 x+y 的结果转换为 int 整型
(float) ; //将数值 100(默认为int类型)转换为 float 类型
     #include <stdio.h>
int main(){
int sum = ; //总数
int count = ; //数目
double average; //平均数
average = (double) sum / count;
printf("Average is %lf!\n", average);
return ;
}

运行结果:
Average is 14.714286!

sum 和 count 都是 int 类型,如果不进行干预,那么sum / count的运算结果也是 int 类型,小数部分将被丢弃;虽然是 average 是 double 类型,可以接收小数部分,但是心有余力不足,小数部分提前就被“阉割”了,它只能接收到整数部分,这就导致除法运算的结果严重失真。

既然 average 是 double 类型,为何不充分利用,尽量提高运算结果的精度呢?为了达到这个目标,我们只要将 sum 或者 count 其中之一转换为 double 类型即可。上面的代码中,我们将 sum 强制转换为 double 类型,这样sum / count的结果也将变成 double 类型,就可以保留小数部分了,average 接收到的值也会更加精确。

在这段代码中,有两点需要注意:

      • 对于除法运算,如果除数和被除数都是整数,那么运算结果也是整数,小数部分将被直接丢弃;如果除数和被除数其中有一个是小数,那么运算结果也是小数。这一点已在《C语言加减乘除运算》中进行了详细说明。
      • ( )的优先级高于/,对于表达式(double) sum / count,会先执行(double) sum,将 sum 转换为 double 类型,然后再进行除法运算,这样运算结果也是 double 类型,能够保留小数部分。注意不要写作(double) (sum / count),这样写运算结果将是 3.000000,仍然不能保留小数部分。

类型转换只是临时性的

自动类型转换 VS 强制类型转换

C语言中,有些类型既可以自动转换,也可以强制转换,例如 int 到 double,float 到 int 等;而有些类型只能强制转换,不能自动转换,例如以后将要学到的 void * 到 int *,int 到 char * 等。

可以自动转换的类型一定能够强制转换,但是,需要强制转换的类型不一定能够自动转换。现在我们学到的数据类型,既可以自动转换,又可以强制转换,以后我们还会学到一些只能强制转换而不能自动转换的类型。

可以自动进行的类型转换一般风险较低,不会对程序带来严重的后果,例如,int 到 double 没有什么缺点,float 到 int
顶多是数值失真。只能强制进行的类型转换一般风险较高,或者行为匪夷所思,例如,char * 到 int *
就是很奇怪的一种转换,这会导致取得的值也很奇怪,再如,int 到 char * 就是风险极高的一种转换,一般会导致程序崩溃。

C语言关于数据类型转换的更多相关文章

  1. C语言:数据类型转换 自动转换 强制转换

    数据类型转换就是将数据(变量.数值.表达式的结果等)从一种类型转换为另一种类型. 自动类型转换 自动类型转换就是编译器默默地.隐式地.偷偷地进行的数据类型转换,这种转换不需要程序员干预,会自动发生.1 ...

  2. c语言,数据类型转换

    在执行算术运算时,计算机比C语言的限制更多.为了让计算机执行算术运算,通常要求操作数有相同的大小(即位的数量相同),并且要求存储的方式也相同.计算机可能可以直接将两个16位整数相加,但是不能直接将16 ...

  3. C语言中数据类型转换的学习

    1. 整型和枚举类型数据的转换 测试代码如下: #include <stdio.h> typedef enum _E_TYPE_T {     E_TYPE_1 = -1,     E_T ...

  4. c语言常用数据类型转换整理

    你要发送原始数据流 还是 格式化输出? 如果是格式化 按原子说的 ,用sprintf / printf; 如果发送原始内存数据流, 可按下面发送, 发送 #define BYTE0(pointer) ...

  5. C语言:数据类型转换

    #include <stdio.h> main() { printf("%d\n",sizeof(1)); printf("%d\n",sizeof ...

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

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

  7. 使用变量 数据类型转换 逻辑控制语句(begin ...end; case...end; if...else; while)

    一:变量 变量分为局部变量和全局变量  (全局变量是系统自定的,是不可手动给值的,若想自己定义全局变量可考虑创建全局临时表!) 局部变量的定义:  declare @变量名  数据类型 (局部变量只能 ...

  8. c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast

    c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast  [版权声明]转载请注明出处 http://www.cnblogs.c ...

  9. JavaScript数据类型转换

    原文转自:http://javascript.ruanyifeng.com/grammar/conversion.html#rd JavaScript是一种动态类型语言,变量是没有类型的,可以随时赋予 ...

随机推荐

  1. CodeForces - 260B

    A recently found Ancient Prophesy is believed to contain the exact Apocalypse date. The prophesy is ...

  2. 题解 CF1286A 【Garland】

    updata on 2020.3.19 往博客园搬的时候看了看自己以前写的blog 其实没多久,才两个多月,感觉自己之前写的东西好罗嗦啊.. 但也是最近写的blog才开始多起来 当然现在也没好到哪去. ...

  3. 如何用Hexo搭建个人博客

    以前用Wordpress搭建过一个博客网站,Wordpress虽然安装简单,功能强大,但是对于个人建站来说有点复杂了.最近发现用Hexo建站很流行,于是将网站从Wordpress迁移到了Hexo. H ...

  4. 内存迟迟下不去,可能你就差一个GC.Collect

    一:背景 1. 讲故事 我们有一家top级的淘品牌店铺,为了后续的加速计算,在程序启动的时候灌入她家的核心数据到内存中,灌入完成后内存高达100G,虽然云上的机器内存有256G,然被这么划掉一半看着还 ...

  5. django3开发完整博客带评价

    纯django开发最完美博客 2020年5月打造最时尚博客系统教程 为了学习速度,集中精力学习django和博客开发, 没有使用其它框架,也没有使用css预处理等 这样学起来最方便, 博客前后端都完成 ...

  6. Jetson AGX Xavier/Ubuntu更改pip3源

    pip3换源: 修改~/.pip/pip.conf,如果没有这个文件,就创建一个. 内容如下: [global]index-url = https://pypi.tuna.tsinghua.edu.c ...

  7. 王颖奇 20171010129《面向对象程序设计(java)》第十七周学习总结

    实验十七  线程同步控制 实验时间 2018-12-10 学习总结: 1.Java通过多线程的并发运行提高系统资源利用 率,改善系统性能. 2.假设有两个或两个以上的线程共享 某个对象,每个线程都调用 ...

  8. 保姆式教学:Typora+图床功能

    众所周知,markdown编辑器typora是一款很好的可视化.所见即所得型的编辑器! 但是,因为图片问题,本菜狗常常不能把某些写好的markdown文档直接复制粘贴进博客而不加修改-- 不过,前几天 ...

  9. MySQL 入门(3):事务隔离

    摘要 在这一篇内容中,我将从事务是什么开始,聊一聊事务的必要性. 然后,介绍一下在InnoDB中,四种不同级别的事务隔离,能解决什么问题,以及会带来什么问题. 最后,我会介绍一下InnoDB解决高并发 ...

  10. java1.8新特性之stream

    什么是Stream? Stream字面意思是流,在java中是指一个来自数据源的元素队列并支持聚合操作,存在于java.util包中,又或者说是能应用在一组元素上一次执行的操作序列.(stream是一 ...