C语言数据类型转换(自动类型转换 强制类型转换)

数据类型转换就是将数据(变量、数值、表达式的结果等)从一种类型转换为另一种类型。

自动类型转换

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

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

float f = 100;

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

int n = f;

f 是 float 类型的数据,需要先转换为 int 类型才能赋值给变量 n。
在赋值运算中,赋值号两边的数据类型不同时,需要把右边表达式的类型转换为左边变量的类型,这可能会导致数据失真,或者精度降低;

所以说,自动类型转换并不一定是安全的。对于不安全的类型转换,编译器一般会给出警告。

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

  • 转换按数据长度增加的方向进行,以保证数值不失真,或者精度不降低。例如,int 和 long 参与运算时,先把 int 类型的数据转成 long 类型后再进行运算。

  • 所有的浮点运算都是以双精度进行的,即使运算中只有 float 类型,也要先转换为 double 类型,才能进行运算。

  • char 和 short 参与运算时,必须先转换成 int 类型。

下图对这种转换规则进行了更加形象地描述:

unsigned 也即 unsigned int,此时可以省略 int,只写 unsigned。

自动类型转换示例:

#include
int main(){
float PI = 3.14159;
int s1, r = 5;
double s2;
s1 = r * r * PI;
s2 = r * r * PI;
printf("s1=%d, s2=%f\n", s1, s2);
return 0;
}

运行结果:
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;  //将数值 100(默认为int类型)转换为 float 类型

下面是一个需要强制类型转换的经典例子:

#include 
int main(){
int sum = 103;  //总数
int count = 7;  //数目
double average;  //平均数
average = (double) sum / count;
printf("Average is %lf!\n", average);
return 0;
}

运行结果:
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,仍然不能保留小数部分。

类型转换只是临时性的

无论是自动类型转换还是强制类型转换,都只是为了本次运算而进行的临时性转换,转换的结果也会保存到临时的内存空间,不会改变数据本来的类型或者值。

声明:

本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338682.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C 为什么非要引入那几种类型转换?

为什么要引入这几种类型转换,它与C语言中的强制类型转换有什么区别?这四种类型转换分别应用在什么场景?C 为什么要引入这几种强制类型转换?我们都知道C 完全兼容C语言,C语言的转换方式很简单,可以在任意类型…

C语言笔试两题,有坑

题目一最近遇到的一个华为笔试题题目:对字符串中的所有单词进行倒排。说明:1、构成单词的字符只有26个大写或小写英文字母;2、非构成单词的字符均视为单词间隔符;3、要求倒排后的单词间隔符以一个空格表示;如果原字符串…

嵌入式linux文件系统启动,嵌入式Linux之文件系统启动分析【原创】

this.p{ m:2,b:2,loftPermalink:,id:fks_094068082086089066084084095095080087080066082082083075,blogTitle:嵌入式Linux之文件系统启动分析【原创】,blogAbstract:author:张继飞写在前面,这一切必须是在Linux内核挂载文件系统后。在Linux内核中找到/i…

C语言:如何定义一个和库函数名一样的函数,并在函数中调用该库函数

某个函数fun_1()是在lib内,没法修改的,在程序中大量的使用了该函数,现在想把原本fun_1失效(现在失效的方法是#define fun_1(..)),用另外一个函数fun_2(),可是fun_2最后也需要调用fun_1,上面的失效方法感觉就不行了,请问…

C语言可变参数只会用算啥本事?看我来抽丝剥茧干翻它!

看山是山,看山不是山,最终看山才是山,并且是无穷的山峦。当我们学习一门技术的时候,起初是先模仿,但是最终是为了超越,也就是得到秘籍,看到本质。于是,今天来继续看可变参数&#xf…

java8升级java12_为什么现在是升级到Java 8的最佳时机

java8升级java12有兴趣了解如何通过AppDynamics充分利用Java 8的新功能吗? 立即开始免费试用 ! 今年3月,Oracle发布了近十年来最受期待的版本Java8。自发布以来,最新版本引起了越来越多的关注,各种规模的公司都渴望升…

C语言#include还有些你不知道的事

#include简介在C语言中#include是preprocessor的一条指令,告诉预处理器将指定头文件的内容插入到预处理器命令的相应位置。#include "xxx.h" 和 #include有两种方式可以指定插入头文件:#include #include "filename"如果需要包含标…

java常见的ide_在三个Java IDE中生成的三种常见方法

java常见的ide在本文中,我研究了NetBeans 8.0.2 , IntelliJ IDEA 14.0.2和Eclipse Luna 4.4.1生成的三种“通用”方法[ equals(Object) , hashCode()和toString() ]的区别…

深度linux安装依赖,Linux -- Ubuntu下载deepin wine依赖问题笔记

问题开始下载deepin-wine安装包, 请稍后…1.1udis86_1.72-2_i3 100%[>] 34.18K 87.3KB/s 用时 0.4s1.2deepin-fonts-win 15%[> ] 31.18K 1.72KB/s 用时 18s1.2deepin-fonts-win 100%[>] 207.88K 26.2KB/s 用时 6.7s2.1deepin-libwine_2 100%[>] 18.97M 132KB/s 用时…

什么是C语言中的隐式函数声明?

「1、什么是C语言的隐式函数声明」在C语言中,函数在调用前不一定非要声明。如果没有声明,那么编译器会自动按照一种隐式声明的规则,为调用函数的C代码产生汇编代码。下面是一个例子:int main(int argc, char** argv) {double x a…

群晖 上传 源文件不存在_群晖NAS连接百度网盘报错?原因是这样的

群晖NAS附带的云同步套件可以与国内外多个网盘连接 , 连接后可从云上下载数据亦可从本地将数据上传到云上。例如通过云同步套件连接百度网盘账号后可以便捷上传和下载数据 , 若网盘空间较大甚至可用来备份整个NAS等。不过现在看来群晖与百度网盘的合作似乎已经结束,…

ssl/tls服务器瞬时_SSL / TLS REST服务器–带有Spring和TomEE的客户端

ssl/tls服务器瞬时在构建系统时,开发人员通常会忽略安全性方面。 安全一直是令人担忧的重要问题,但是它比以前吸引了更高的关注。 就在今年,我们发生了像Heartbleed Bug或CelebrityGate丑闻这样的案件。 这与帖子无关,只是安全真正…

linux kvm百度云,容器与云|如何在 Ubuntu Linux 上使用 KVM 云镜像

如何下载并使用运行在 Ubuntu Linux 服务器上的 KVM 云镜像?如何在 Ubuntu Linux 16.04 LTS 服务器上无需完整安装即可创建虚拟机?如何在 Ubuntu Linux 上使用 KVM 云镜像?基于内核的虚拟机(KVM)是 Linux 内核的虚拟化模块,可将其…

C 的16个大坑,你能躲过几个?

首先说下C 和C语言有什么区别?分享一个我在知乎上看见的回答:C ≈ C with classes, C with STLC:面向机器编程C :面向编译器编程C 有个很重要的特性叫RAII,个人认为可以多多使用,相当方便。言归…

java 性能调优_Java性能调优调查结果(第三部分)

java 性能调优这是本系列文章的第三篇,我们将分析2014年10月进行的调查的结果。如果您尚未这样做,我建议从本系列的前两篇文章开始: 问题严重性分析和监视域分析 。 这篇文章着重于故障排除/根本原因检测。 本调查部分的背景:意识…

不懂指针类型,7个例子给你讲明白

1. int va;这是一个整型变量,32位CPU的话,占有32个bite2. int *va;这是一个整型指针变量,用于存放一个整型变量的地址,3. int **va;这是一个整型的二级指针,用于存放一个内存的地址,该地址对应的内存中存放…

Tomcat与Netty比较

Tomcat介绍Tomcat支持的协议Tomcat的优缺点Netty介绍Netty支持的协议Netty的优点和缺点Tomcat和Netty的区别Tomcat和Netty的应用场Tomcat和Netty来处理大规模并发连接的优化Tomcat与Netty的网络模型的区别Tomcat与Netty架构设计拓展 Tomcat介绍 Tomcat是一个免费的、开放源代码…

C或C 如何通过程序执行shell命令并获取命令执行结果?

1 应用场景最近在实际程序开发中,需要通过程序执行 shell 命令,并获取命令输出内容。但是系统自带的 system 只能返回命令执行成功与否,不能捕获命令输出。2 扩展性由于应用场景本就广泛,因此扩展性较好。此函数可以执行任意命令&…

linux centos7安装ngix,centos7 环境下安装nginx--Linux

本文将要为您介绍的是centos7 环境下安装nginx--Linux,具体完成步骤:一、安装前需要的编译环境准备1、安装makeyum install -y gcc automake autoconf libtool make2、安装gcc、gcc-cyum install -y gcc gcc-c3、关闭防火墙iptables -F4、关闭selinux#临时关闭:sete…

primefaces_使用PrimeFaces开发数据导出实用程序

primefaces我的日常工作涉及大量使用数据。 我们使用关系数据库来存储所有内容,因为我们依赖于企业级的数据管理。 有时,具有将数据提取为简单格式(例如电子表格)的功能很有用,以便我们可以按需进行操作。 这篇文章概述…