百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

「揭秘」C语言类型转换时发生了什么?

liebian365 2024-12-27 16:17 33 浏览 0 评论

在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. 编译器把设定的数值放到这个内存空间,是数据类型的存储方式解析后存进去的。

总结强调一点

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

相关推荐

go语言也可以做gui,go-fltk让你做出c++级别的桌面应用

大家都知道go语言生态并没有什么好的gui开发框架,“能用”的一个手就能数的清,好用的就更是少之又少。今天为大家推荐一个go的gui库go-fltk。它是通过cgo调用了c++的fltk库,性能非常高...

旧电脑的首选系统:TinyCore!体积小+精简+速度极快,你敢安装吗

这几天老毛桃整理了几个微型Linux发行版,准备分享给大家。要知道可供我们日常使用的Linux发行版有很多,但其中的一些发行版经常会被大家忽视。其实这些微型Linux发行版是一种非常强大的创新:在一台...

codeblocks和VS2019下的fltk使用中文

在fltk中用中文有点问题。英文是这样。中文就成这个样子了。我查了查资料,说用UTF-8编码就行了。edit->Fileencoding->UTF-8然后保存文件。看下下边的编码指示确...

FLTK(Fast Light Toolkit)一个轻量级的跨平台Python GUI库

FLTK(FastLightToolkit)是一个轻量级的跨平台GUI库,特别适用于开发需要快速、高效且简单界面的应用程序。本文将介绍Python中的FLTK库,包括其特性、应用场景以及如何通过代...

中科院开源 RISC-V 处理器“香山”流片,已成功运行 Linux

IT之家1月29日消息,去年6月份,中科院大学教授、中科院计算所研究员包云岗,发布了开源高性能RISC-V处理器核心——香山。近日,包云岗在社交平台晒出图片,香山芯片已流片,回片后...

Linux 5.13内核有望合并对苹果M1处理器支持的初步代码

预计Linux5.13将初步支持苹果SiliconM1处理器,不过完整的支持工作可能还需要几年时间才能完全完成。虽然Linux已经可以在苹果SiliconM1上运行,但这需要通过一系列的补丁才能...

Ubuntu系统下COM口测试教程(ubuntu port)

1、在待测试的板上下载minicom,下载minicom有两种方法:方法一:在Ubuntu软件中心里面搜索下载方法二:按“Ctrl+Alt+T”打开终端,打开终端后输入“sudosu”回车;在下...

湖北嵌入式软件工程师培训怎么选,让自己脱颖而出

很多年轻人毕业即失业、面试总是不如意、薪酬不满意、在家躺平。“就业难”该如何应对,参加培训是否能改变自己的职业走向,在湖北,有哪些嵌入式软件工程师培训怎么选值得推荐?粤嵌科技在嵌入式培训领域有十几年经...

新阁上位机开发---10年工程师的Modbus总结

前言我算了一下,今年是我跟Modbus相识的第10年,从最开始的简单应用到协议了解,从协议开发到协议讲解,这个陪伴了10年的协议,它一直没变,变的只是我对它的理解和认识。我一直认为Modbus协议的存...

创建你的第一个可运行的嵌入式Linux系统-5

@ZHangZMo在MicrochipBuildroot中配置QT5选择Graphic配置文件增加QT5的配置修改根文件系统支持QT5修改output/target/etc/profile配置文件...

如何在Linux下给zigbee CC2530实现上位机

0、前言网友提问如下:粉丝提问项目框架汇总下这个网友的问题,其实就是实现一个网关程序,内容分为几块:下位机,通过串口与上位机相连;下位机要能够接收上位机下发的命令,并解析这些命令;下位机能够根据这些命...

Python实现串口助手 - 03串口功能实现

 串口调试助手是最核心的当然是串口数据收发与显示的功能,pzh-py-com借助的是pySerial库实现串口收发功能,今天痞子衡为大家介绍pySerial是如何在pzh-py-com发挥功能的。一、...

为什么选择UART(串口)作为调试接口,而不是I2C、SPI等其他接口

UART(通用异步收发传输器)通常被选作调试接口有以下几个原因:简单性:协议简单:UART的协议非常简单,只需设置波特率、数据位、停止位和校验位就可以进行通信。相比之下,I2C和SPI需要处理更多的通...

同一个类,不同代码,Qt 串口类QSerialPort 与各种外设通讯处理

串口通讯在各种外设通讯中是常见接口,因为各种嵌入式CPU中串口标配,工业控制中如果不够还通过各种串口芯片进行扩展。比如spi接口的W25Q128FV.对于软件而言,因为驱动接口固定,软件也相对好写,因...

嵌入式linux为什么可以通过PC上的串口去执行命令?

1、uboot(负责初始化基本硬bai件,如串口,网卡,usb口等,然du后引导系统zhi运行)2、linux系统(真正的操作系统)3、你的应用程序(基于操作系统的软件应用)当你开发板上电时,u...

取消回复欢迎 发表评论: