ID:技术让梦想更伟大

作者:李肖遥

链接:https://mp.weixin.qq.com/s/ZFf3imVaJgeesuhl1Kn9sQ

在C语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统,我们常用的算术类型包括两种类型:整数类型和浮点类型。那么相互之间具体是怎么转化的呢?

了解一下类型转换

不同数据类型的存储大小和值范围是不一样的,程序在初始化的时候就已经设定了,例如:

int a = 9;
float b = 8.5;

a,b占的字节大小不一样,这个我们应该都知道,在C语言中一个表达式允许不同类型的数据进行运算,例如:

int a = 9;
float b = 8.5,c;
c = a + b;

因为计算机硬件在进行算术操作时,要求各操作数的类型具有相同的存储位数以及一样的存储方式,所以就出现了类型转换。

对于某些类型的转换,编译器可以隐式地自动进行,这种转换称为自动类型转换

而有些类型转换需要程序员显式指明,那么通常把这种转换称为强制类型转换

自动类型转换

自动转换是在源类型和目标类型兼容以及目标类型广于源类型时发生一个类型到另一类的转换。我们先来看一段代码

//vs2019
//来源:技术让梦想更伟大
//作者:李肖遥
#include <stdio.h>
int main()
{
//定义一个整型指针变量pPoint
int* pPoint; //定义基本的数据的类型
char c;
short s;
int i;
long l;
float f;
double d; //将整型浮点型数据赋值给指针类型
pPoint = c;
pPoint = s;
pPoint = i;
pPoint = l;
pPoint = f;
pPoint = d; return 0;
}

由于指针变量和整型、浮点这些数据型的类型是不能相互赋值的,编译报错输出:

那么我们把同类型数据类型进行运算后赋值呢?

//vs2019
//来源:技术让梦想更伟大
//作者:李肖遥
#include <stdio.h>
int main()
{
//定义一个整型指针变量pPoint
int* pPoint; //定义基本的数据的类型
char c;
short s;
int i;
long l;
float f;
double d; //将整型浮点型数据运算之后赋值给指针类型
pPoint = c + c;
pPoint = s + s;
pPoint = i + i;
pPoint = l + l;
pPoint = f + f;
pPoint = d + d; return 0;
}
  • char同类型运算,结果是一个int类型。
  • short同类型运算,结果是一个int类型。
  • int同类型运算,结果是一个int类型。
  • long同类型运算,结果是一个long类型。
  • float同类型运算,结果是一个float类型。
  • double同类型运算,结果是一个double类型。

如下图所示:

同类型运算中:

  • 整型:比int小的,都会转换成int,比int大的不变。
  • 浮点:不变。

那么我们把不同类型数据类型进行运算后赋值呢?

//vs2019
//来源:技术让梦想更伟大
//作者:李肖遥
#include <stdio.h>
int main()
{
//定义一个整型指针变量pPoint
int* pPoint; //定义基本的数据的类型
char c;
short s;
int i;
long l;
float f;
double d; //将整型浮点型数据混合运算赋值给指针类型
pPoint = c + s; // char + short = int
pPoint = c + i; // char + int = int
pPoint = c + l; // char + long = int
pPoint = c + f; // char + float = long
pPoint = c + d; // char + double = float return 0;
}
  • char类型与short类型运算,结果是一个int类型。
  • char类型与int类型运算,结果是一个int类型。
  • char类型与long类型运算,结果是一个long类型。
  • char类型与float类型运算,结果是一个float类型。
  • char类型与double类型运算,结果是一个double类型。

结果如下图所示:

可以得出在不同类型运算中:

  • 如果两边均比int小或等于int,那么结果为int。
  • 如果两边有比int大的,那么结果为比int大的类型。

我们得到结论如图:

  • 整型类型级别从低到高依次为:

    int -> unsigned int -> long -> unsigned long -> long long -> unsigned long long

  • 浮点型级别从低到高依次为:

    float -> double

自动转换规则:

  • 图中横向箭头表示必须的转换,如两个float型数参加运算,虽然它们类型相同,但仍要先转成double型再进行运算,结果亦为double型。
  • 图中纵向箭头表示当运算符两边的运算数为不同类型时的转换,如一个long 型数据与一个int型数据一起运算,需要先将int型数据转换为long型, 然后两者再进行运算,结果为long型。
  • 当较高类型的数据转换为较低类型时,则可能有些数据丢失。
  • 当较低类型的数据转换为较高类型时,一般只是形式上有所改变, 而不影响数据的实质内容。
  • 所有这些转换都是由系统自动进行的,使用时你只需从中了解结果的类型即可。

强制类型转换

强制类型转换是通过类型转换运算来实现的。其一般形式为:

(类型说明符) (表达式)

其作用就是把表达式的运算结果强制转换成类型说明符所表示的类型的值。

//vs2019
//来源:技术让梦想更伟大
//作者:李肖遥
#include<stdio.h>
#include<string.h> int main()
{
float f,x=1.3,y=1.4;
int i = 4,a,b;
a = x + y;
b = (int)(x+y);
f = 10/i;
printf("a=%d,b=%d,f=%f,x=%f,y=%f\n",a,b,f,x,y);
}

运行结果如下:

我们从中可以看到,虽然x,y变强制转换int型,但是最后输出的值不变,强制类型转换没有影响x和y变量原本的类型。而上图警告已经说明了一切。

注意:在C语言中,对一个变量赋值的时候,这个变量初始定义的类型包含了两层含义:

  1. 这个数据类型表示的内存空间的大小。
  2. 编译器把设定的数值放到这个内存空间,是数据类型的存储方式解析后存进去的。

总结强调一点

进行强制类型转换后,内存空间里面的内容是不会发生改变的,改变的是运算时的临时数据对象的类型,是你去读取这个内存空间时的解析方法。所以,一定要对这个数据类型的内存空间和解析方式有一个清晰的认知。

【揭秘】C语言类型转换时发生了什么?的更多相关文章

  1. 执行 $Gulp 时发生了什么 —— 基于 Gulp 的前端集成解决方案(二)

    前言 文章 在windows下安装gulp —— 基于 Gulp 的前端集成解决方案(一) 中,已经完成对 gulp 的安装,由于是window环境,文中特意提到了可以通过安装 gitbash 来代替 ...

  2. 使用C/C++,赋值运算时发生的转换

    使用C/C++,赋值运算时发生的转换主要有以下四种情况 一: 两边类型不同: 结果: 自动完成类型转换! 二: 长数赋给短数: 结果: 截取长数的低位送给短数! 三: 短数赋给长数: 结果: 原来是什 ...

  3. Access Violations 访问冲突(AVs)是Windows编程时发生的最麻烦的错误?

    Access Violations<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office&qu ...

  4. C语言类型转换原理

    C语言类型转换 int a; a=1.23 这里把1.23赋值给a发生了隐式转换,原理如下: int a; float b=3.14; a=b; b赋值给a的过程:首先找一个中间变量是a的类型(该例中 ...

  5. 解决vs创建或打开C++浏览数据库文件*.sdf时发生错误的问题

    VS2012,  创建或打开C++浏览数据库文件*.sdf时发生错误. IntelliSense 和浏览信息将不能用于C++项目. 请确保已安装 Microsoft SQL Server Compac ...

  6. 录像时调用MediaRecorder的start()时发生start failed: -19错误

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  7. 【已解决】Https请求——基础连接已经关闭 发送时发生错误

    本人在做商用项目的推送消息功能时,借助第三方推送服务.这里避免有打广告的嫌疑,就不报名字了.由于是通过调用API接口,所以Post方法是自己写的,但是在开发环境是可以正常推送的,但是一上线就出各种问题 ...

  8. SVN“验证位置时发生错误”的解决办法

    验证位置时发生错误:“org.tigris.subversion.javahl.ClientException...... 验证位置时发生错误:“org.tigris.subversion.javah ...

  9. 使用wget命令时发生错误

    用的是centos6.5, 当我使用命今 sudo wget https://cmake.org/files/v3.6/cmake-3.6.1.tar.gz 下载个cmake的包时, 发生了这样的错误 ...

随机推荐

  1. 绕过PowerShell执行策略方法总结

    默认情况下,PowerShell配置为阻止Windows系统上执行PowerShell脚本.对于渗透测试人员,系统管理员和开发人员而言,这可能是一个障碍,但并非必须如此. 什么是PowerShell执 ...

  2. Spring事务方法上增加synchronized真的有效果吗?

    此文转载,Spring事务本身是一个非常复制的问题,再加上线程并发处理就更加要主要了,由于再开发中有很多朋友会范与下文同样的错误,因分享给大家. 前言 Spring事务的一个奇怪的问题. 朋友问了我一 ...

  3. Qt布局的简单介绍

    1  介绍 参考视频:https://www.bilibili.com/video/BV1XW411x7NU?p=25 布局的好处:布局之后,改变主窗口大小,其余窗口可以自适应. 2  布局分类 垂直 ...

  4. 【SpringBoot MQ 系列】RabbitListener 消费基本使用姿势介绍

    [MQ 系列]RabbitListener 消费基本使用姿势介绍 之前介绍了 rabbitmq 的消息发送姿势,既然有发送,当然就得有消费者,在 SpringBoot 环境下,消费可以说比较简单了,借 ...

  5. 入门大数据---Spark车辆监控项目

    一.项目简介 这是一个车辆监控项目.主要实现了三个功能: 1.计算每一个区域车流量最多的前3条道路. 2.计算道路转换率 3.实时统计道路拥堵情况(当前时间,卡口编号,车辆总数,速度总数,平均速度) ...

  6. 《Java并发编程之美》

    简介 码云笔记 java-concurrent/TheBeautyOfConcurrentProgram

  7. webstom 汉化,激活

    1.激活 本地服务器激活: 下载 magnet:?xt=urn:btih:2289E4F8CEB346AC44E54C8C0DA706CC537301AA 得到一个压缩包IntelliJIDEALic ...

  8. java中的四种访问权限是?

    1.私有权限(private) private可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外部类,不考虑内部类).被private修饰的成员,只能在定义它们的类中使用,在其他类中不能调用. ...

  9. 缺少对公共可见类型或成员的XML注释

    最近突然心血来潮,想清理下代码,结果看到了一堆这样的警告——缺少对公共可见类型或成员“XXX”的 XML 注释: 其实要想取消上面的警告,仅仅需要在项目属性里找到生成页签里的”错误和警告“项,在禁止显 ...

  10. Redis系列(八):发布与订阅

    Redis的发布与订阅,有点类似于消息队列,发送者往频道发送消息,频道的订阅者接收消息. 1. 发布与订阅示例 首先,在本机开启第1个Redis客户端,执行如下命令订阅blog.redis频道: SU ...