当前位置: 首页 > news >正文

一篇文章带你看清C语言中的类型转换规则

我们平时在学习编程以及平时在进行编程练习的时候,经常会碰见那些类型转换的方面,有的时候我么需要进行强制转换,但有的时候系统却可以自动为我们转换,这到底是为什么呢?下面我们就来了解一下C语言中的类型转换规则吧。

我们所学习的数据有不同的类型,不同类型数据之间进行混合运算时必然涉及到类型的转换问题。在C/C++类型转换中,主要分为两种即:隐式类型转换(自动转换)、显式类型转换(强制类型转换)。

  1. 自动转换(隐式转换):遵循一定的规则,由编译系统自动完成。
  2. 强制类型转换(显示转换):把表达式的运算结果强制转换成所需的数据类型。

这时我们就要了解一个数据转换的基本原则:占用内存字节数少(值域小)的类型,向占用内存字节数多(值域大)的类型转换,以保证精度不降低。

隐式转换 

所谓隐式类型转换,是指不需要用户干预,编译器默认进行的类型转换行为(很多时候用户可能都不知道到底进行了哪些转换)。

隐式类型转换一般分为两种:内置数据类型、自定义数据类型。

内置数据类型

内置数据类型转换的原则也就遵循了我们上面所提到的原则,就是一定要从低精度到高精度去转换才行。

#include <stdio.h>

int main()
{
	int num = 5;
	printf("s1=%d\n", num / 2);
	printf("s2=%lf\n", num / 2.0);

	return 0;
}

通过我们的运算结果图,也不难发现我们的数据从整形转换为了浮点型,这就发生了一次隐式转换。

所以我们在进行运算时,对于除法运算,如果除数和被除数都是整数,那么运算结果也是整数,小数部分将被直接丢弃;如果除数和被除数其中有一个是小数,那么运算结果也是小数。 

如果我们不去满足原则的进行隐式转换,那么编译器将会提示编译告警。 

自定义数据类型

内置数据类型的转换风险是很小的,所以隐式类型转换的风险一般存在于自定义类型转换间。尤其需要注意自定义类的构造函数。

class MyString
{
	 public:
		     MyString(int n) {}; // 预先分配n个字节给字符串
		     MyString(const char* p) {}; // 用C风格的字符串p作为初始化值 

	 };
 
 void main()
 {
	     MyString s1 = "China";	 //成功 隐式转换,等价于MyString s1 = MyString(”China”) 
	     MyString s2(10); 	//成功 分配10个字节的空字符串
	     MyString s3 = MyString(10); //成功 分配10个字节的空字符串
	 
	     MyString s4 = 10; //成功,编译通过。也是分配10个字节的空字符串
	     MyString s5 = 'A'; // 编译通过。分配int('A')个字节的空字符串
	    
	 }

在 s4 和s5 中,分别把一个int型和char型,隐式转换成了分配若干字节的空字符串,这样会容易令人误解。

显示转换

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

显示转换(强制类型转换)指的是使用强制类型转换运算符,将一个变量或表达式转化成所需的类型,其基本语法格式如下所示:

(类型说明符) (表达式)
#include <stdio.h>

int main()
{
	float x = 0 ;
	int i = 0 ;
	x = 3.f ;
	
	i = x ;			//x为实型, i为整型,直接赋值会有警告
	i = (int)x ;		//使用强制类型转换
	
	printf("x=%f, i=%d\n", x, i) ;
	
	return 0 ;
}

上面那段代码,后面的i就是使用的强制转换将其从高精度的float类型转化为低精度的int类型,这是在隐式转换中无法做到的一点。

类型转换的临时性

不论是隐式类型转换还是显示类型转换,都只是为了本次运算而进行的临时性转换,转换的结果也会保存到临时的内存空间,所以不会改变数据本来的类型或者值。

#include <stdio.h>


int main(){
	double a = 205.8;  
	int b = 7;  
	double c;  
	
	
	int a_int = (int)a;
	c = a / b;
	
	printf("a=%lf, a_int=%d, c=%lf\n", a, a_int, c);
	
	return 0;
}

通过结果我们也不难看出,类型转换是临时的,并不会去改变改变了自身的类型。

两种转换类型的优缺点

在C语言中,有些类型既可以自动转换,也可以强制转换,例如 int 到 double,float 到 int 等;而有些类型只能强制转换,不能自动转换

可以自动转换的类型一定能够强制转换,但是,需要强制转换的类型不一定能够自动转换。现在我们学到的数据类型,既可以自动转换,又可以强制转换,以后我们还会学到一些只能强制转换而不能自动转换的类型。
可以自动进行的类型转换风险较低,不会对程序带来严重的后果,但是只能强制进行的类型转换一般风险较高,或者行为匪夷所思,会导致你得到的结果很奇怪或者导致程序的崩溃。

所以在使用强制类型转换时,程序员自己要意识到潜在的风险。

相关文章:

  • 单海军:行业AI平台赋能金融企业数智化转型
  • Jmeter接口自动化(十)断言
  • C++ 小游戏 视频及资料集(7)
  • 计算机网络笔记(王道考研) 第二章:物理层
  • TCP的连接过程——三次握手和四次挥手
  • tensorflow2从入门到精通——DCGAN算法实现
  • 反欺诈黑产总结
  • 学术报告系列(七) - Critical Scenario Based SOTIF Validation Method
  • [ vulhub漏洞复现篇 ] JBOSS AS 5.x/6.x反序列化远程代码执行漏洞CVE-2017-12149
  • UE4 Http协议实现Web登陆与注册
  • 【线性代数基础进阶】二次型-补充+练习
  • mybatis-mybatis连接sqlserver数据库,maven
  • 融云 IM 即时通讯的跨应用通信能力
  • 行业发展解读:互联网人,如何“变道”自动驾驶?
  • 什么蓝牙耳机适合运动、运动用的蓝牙耳机推荐
  • [ 一起学React系列 -- 8 ] React中的文件上传
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • Android框架之Volley
  • angular2开源库收集
  • Django 博客开发教程 8 - 博客文章详情页
  • echarts花样作死的坑
  • github从入门到放弃(1)
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • Java精华积累:初学者都应该搞懂的问题
  • jquery ajax学习笔记
  • MD5加密原理解析及OC版原理实现
  • passportjs 源码分析
  • Redis 中的布隆过滤器
  • select2 取值 遍历 设置默认值
  • Travix是如何部署应用程序到Kubernetes上的
  • TypeScript迭代器
  • Vue.js源码(2):初探List Rendering
  • vue-router 实现分析
  • Vue学习第二天
  • 分布式熔断降级平台aegis
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 讲清楚之javascript作用域
  • 开源SQL-on-Hadoop系统一览
  • 前端_面试
  • 前端面试之CSS3新特性
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 【云吞铺子】性能抖动剖析(二)
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • #Z2294. 打印树的直径
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (33)STM32——485实验笔记
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (排序详解之 堆排序)
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (转)JAVA中的堆栈
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • ***检测工具之RKHunter AIDE