【新书推荐】3.7 数据类型转换

本节必须掌握的知识点:

   整型提升

   浮点型和整型转换

   浮点型转换

   普通算术类型转换

   示例十二

       在实际项目应用过程中,我们通常会根据实际需要,对数据进行扩展和截取,我们称之为数据类型转换。对数据类型的转换需要遵循以下规则。

3.7.1 整型提升

在可以使用int型或unsigned int型的表达式中,也可以使用有符号或无符号类型的char、short int、int类型,还可以使用枚举对象。可根据实际需要确定数据类型。

无论哪种情况,如果int型可以表示出原数据类型的所有值,就将值转换为int型,否则转换为unsigned int型。VS编译器默认缺省的数据类型为int类型。

整型提升不会改变符号和数值。char型是否作为有符号类型来处理,由编译器而定。VS编译器中char型作为有符号整型处理,取值范围-128~127。

有符号整型和无符号整型

整数类数据类型之间互相转换时,若原数值能用转换后的数据类型表示,则数值不会发生变化。

举例

    //有符号整型提升

    short int a = 123;

    int b = (int)a;//b = 123,short int类型转换为int类型,(int)可省略

printf("a = %d,b = %d\n", a, b);

输出结果:a = 123,b = 123 原值没有发生变换

有符号整数转换为位数相同或位数更多的无符号整数时,如果该有符号整数不为负数,则数值不会发生变化。

否则,若无符号整数的位数较大,则先将有符号整数提升为与无符号整数长度相同的有符号整数。然后再与无符号整数类型可表示的最大数加1后的值相加,将有符号整数转换为无符号整数。

举例

       //有符号整型提升为无符号整型:正整数

    unsigned int c = (unsigned)b; //(unsigned)可省略

    printf("b = %d,c = %u\n", b, c);

    //有符号整型提升为无符号整型:负整数

    short int d = -1;

    unsigned int e = (unsigned)d; //e=4294967295,强制类型转换(unsigned)可省略

    printf("d = %d,e = %u\n", d, e);

    输出结果:

b = 123,c = 123         //有符号整型提升为无符号整型:正整数不变

d = -1,e = 4294967295   //有符号整型提升为无符号整型:负整数变为4294967295

    有符号数转换过程:

    第一步:先将16位short有符号类型变量d提升为32位有符号类型-1(16进制数0ffffh提升为0ffffffffh)。

    32位有符号类型0ffffffffh+1+32位无符号整型最大值0ffffffffh,等于0ffffffffh(十进制数4294967295)。

将整数类数据类型转换为位数更少的无符号整数时,除以比位数较少的数据类型可表示的最大符号数大1的数,所得的非负余数就是转换后的值。

将整数类数据类型转换为位数更少的有符号整数时,以及将无符号整数转换为位数相同的有符号整数时,如果不能正确表示转换后的值,则此时的操作由编译器而定。

举例

       //有符号int整型转为无符号unsigned short类型

    int f = -1;

    unsigned short g = (unsigned short)f;//g=65535,0xffffffff截取为0ffffh

    printf("f = %d,g = %d\n", f, g);

    //有符号int整型转为无符号short类型

    short h = (short)f;// 0xffffffff截取为0ffffh

    printf("f = %d,h = %d\n", f, h);//h=-1

    //无符号unsigned int整型转为有符号short、int类型

    unsigned int i = 4294967295;//十六进制数0xffffffff

    short j = (short)i; // 0xffffffff截取为0ffffh

    int k = (int)i; // 0xffffffff保持不变

    printf("i = %u,j = %d,k = %d\n", i, j,k);//j=-1,k=-1

       输出结果:

       f = -1,g = 65535

f = -1,h = -1

i = 4294967295,j = -1,k = -1

其实没有那么复杂,只需要将整数转换为十六进制数,然后截取缩短后的位数即可。

3.7.2 浮点型和整型转换

将浮点型的值转换为整数类数据类型时,会截断小数部分。整数部分的值不能用整数类数据类型表示时的操作未定义。

将整数类数据类型的值转换为浮点型时,如果数据类型转换后的结果在数值范围内不能正确表示,那么会根据编译器定义的方法取大于或小于原值的最接近的近似值作为转换结果。

举例

    //整型转换为浮点型

    int x = 123;

    double y = (double)x;//y=123.000000,强制类型转换(double)可省略

    printf("x = %d,y = %f\n", x, y);

    //浮点类型转换为整型

    double n = 123.123;

    int m = (int)n;

    printf("n = %f,m = %d\n", n, m);

       输出结果:

       x = 123,y = 123.000000

n = 123.123000,m = 123

浮点型转整型,截取整数部分。整型转浮点型,填充小数部分为0。

3.7.3 浮点型转换

float型提升为double型或long double型时,以及double 型提升为 long double型时,值不会发生变化。

double型转换为float型时,以及long double型转换为float型时,会根据编译器定义的方法取大于或小于原值的最接近的近似值作为转换结果。

举例

    //浮点型相互转换

    float w = (float)123.123456; //默认浮点常量值为double类型

    double z = (double)w;

    double p = 123.123456789;

    float l = (float)p;

    printf("w = %f,z = %f,p = %f,l = %f\n", w, z, p,l);

       输出结果:

       w = 123.123459,z = 123.123459,p = 123.123457,l = 123.123459

浮点类型转换后的值为近似值。长浮点型转短浮点型需要截掉后面的小数值。短浮点型转长浮点型尾数部分填充0。

3.7.4 普通算术类型转换

许多具有算术类型操作数的双目运算符都会执行操作数的数据类型转换,并用同样的方法决定转换结果的数据类型。数据类型转换的目的是通用数据类型,该数据类型亦是转换结果的数据类型。这一过程称为普通算术类型转换。

规则如下

若有一个操作数为long double型,则将另一个操作数转换为long double型。

若有一个操作数为double型,则将另一个操作数转换为double型。

若有一个操作数为float型,则将另一个操作数转为float型。

若均不符合以上情况,则根据以下规则对两个操作数进行整型提升。

若有一个操作数为unsigned long型,则将另一个操作数提升为unsigned long型。

在一个操作数为long型,另一个操作数为unsigned型的操作数转换为long型。如果long型不能表示unsigned型的值,则将两个操作数转换为unsigned long型。

若有一个操作数为long型,则将另一个操作数转换为long型。

若有一个操作数为unsigned型,则将另一个操作数转换为unsigned型。

否则将两个操作数都转换为int型。

浮点型操作数的值以及浮点型表达式的结果可以超出数据类型所要求的精度和范围进行显示。但是结果的数据类型不会发生变化。

举例

    long double a = 1.0;

    double b = 2.0;

    float c = 3.0;

    unsigned d = 4.0;

    unsigned long k = 10.0;

    long e = 5.0;

    int f = 6.0;

    unsigned h = 7.0;

    short i = 8.0;

    unsigned short j = 9.0;

    (a + b) //double b 转换为long double类型

    (b + c) //float c 转换为double类型

    (c + d) // unsigned d 转换为float类型

    (c + d) // unsigned d 转换为float类型

    (k + d) // unsigned d 转换为unsigned long类型

    (e + f) // int f 转换为long类型

(f + h) // int f 转换为unsigned int类型

(f + i) // short i 转换为int类型

(f + j) // unsigned short j 转换为int类型

 

结论

       自动类型转换:

当较短数据类型转换为较长数据类型时,不会丢失精度,可以省略强制类型转换,编译器会自动进行数据类型转换。

自动类型转换规则:

1.若参与运算量的类型不同,则先转换成同一类型,然后进行运算。

2.转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。

①若两种类型的字节数不同,转换成字节数高的类型。

②若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型。

3.所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。

4char型和short型(在visual c++等环境下)参与运算时,必须先转换成int型。

5.在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度,丢失的部分直接舍去。

       强制类型转换:

当较长数据类型转换为较短数据类型时,会丢失精度,需要使用强制数据类型转换。

3.7.5 示例十二

/*

   数据类型转换

*/

#include <stdio.h>

#include <stdlib.h>

int main(void)

{

    //有符号整型提升

    short int a = 123;

    int b = (int)a;//b = 123,short int类型转换为int类型,(int)可省略

    printf("a = %d,b = %d\n", a, b);

    //有符号整型提升为无符号整型:正整数

    unsigned int c = (unsigned)b;//(unsigned)可省略

    printf("b = %d,c = %u\n", b, c);

    //有符号整型提升为无符号整型:负整数

    short int d = -1;

    unsigned int e = (unsigned)d;//e=4294967295强制类型转换(unsigned)可省略

    printf("d = %d,e = %u\n", d, e);

    //有符号int整型转为无符号unsigned short类型

    int f = -1;

    unsigned short g = (unsigned short)f;//g=65535

    printf("f = %d,g = %d\n", f, g);

    //有符号int整型转为无符号short类型

    short h = (short)f;

    printf("f = %d,h = %d\n", f, h);//h=-1

    //无符号unsigned int整型转为有符号short、int类型

    unsigned int i = 4294967295;//十六进制数0xffffffff

    short j = (short)i;

    int k = (int)i;

    printf("i = %u,j = %d,k = %d\n", i, j,k);//j=-1,k=-1

    //整型转换为浮点型

    int x = 123;

    double y = (double)x;//y=123.000000,强制类型转换(double)可省略

    printf("x = %d,y = %f\n", x, y);

    //浮点类型转换为整型

    double n = 123.123;

    int m = (int)n;

    printf("n = %f,m = %d\n", n, m);

    //浮点型相互转换

    float w = (float)123.123456;//默认浮点常量值为double类型

    double z = (double)w;

    double p = 123.123456789;

    float l = (float)p;

    printf("w = %f,z = %f,p = %f,l = %f\n", w, z, p,l);

    system("pause");

    return 0;

}

    ●输出结果:

    a = 123,b = 123

b = 123,c = 123

d = -1,e = 4294967295

f = -1,g = 65535

f = -1,h = -1

i = 4294967295,j = -1,k = -1

x = 123,y = 123.000000

n = 123.123000,m = 123

w = 123.123459,z = 123.123459,p = 123.123457,l = 123.123459

请按任意键继续. . .

    代码分析(略)

    汇编解析(略)

本文摘自编程达人系列教材《汇编的角度——C语言》。

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

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

相关文章

毕业论文格式

官方格式 编号格式&#xff1a; 【论文标题设置】论文一二三级标题设置_哔哩哔哩_bilibili 编号和文字的间距太大怎么办&#xff1f;两招轻松解决&#xff01;

倒计时80天

1.J-兔子不会种树_浙江机电职业技术学院第八届新生亮相赛&#xff08;同步赛&#xff09; (nowcoder.com) /****** __----~~~~~~~~~~~------___* . . ~~//...... __--~ ~~…

前端——JavaScript

目录 文章目录 前言 一. JavaScript基础 1.JavaScript基本结构 2. JavaScript 执行过程 3. JavaScript 引入方式 二. JavaScript 语法 1.数据类型 2.变量 2.1 var 关键字定义变量 2.2 let 关键字定义变量 2.3 var 与 let 的区别 3.字符串 3.1定义字符串 3.2 字…

Java中this引用详解

文章目录 一、 为什么要有this引用二、什么是this引用三、this引用的特性四、如何用好this关键字 一、 为什么要有this引用 我们先看一段代码 class Data {public int year;public int month;public int day;public void setDay(int y,int m,int d) {year y;month m;day d…

安卓反编译机制,应用场景以及工具解析

一、引言 随着移动应用的普及&#xff0c;安卓系统成为了市场上的主流操作系统之一。然而&#xff0c;安卓应用的源代码往往受到版权保护&#xff0c;开发者需要对其安全性进行维护。此时&#xff0c;反编译技术应运而生&#xff0c;成为保障应用安全的重要手段。 本文将详细介…

《动手学深度学习(PyTorch版)》笔记4.7

Chapter4 Multilayer Perceptron 4.7 Forward/Backward Propagation and Computational Graphs 本节将通过一些基本的数学和计算图&#xff0c;深入探讨反向传播的细节。首先&#xff0c;我们将重点放在带权重衰减&#xff08; L 2 L_2 L2​正则化&#xff09;的单隐藏层多层…

15. 扩展: Spring Boot CORS支持

Spring Boot CORS支持 跨源资源共享(CORS)是一种安全概念&#xff0c;用于限制Web浏览器中实现的资源。 它可以防止JavaScript代码产生或消耗针对不同来源的请求。 例如&#xff0c;Web应用程序在8080端口上运行&#xff0c;并且使用JavaScript尝试从9090端口使用RESTful Web服…

【教学类-44-04】20240128汉字字帖的字体(一)——文艺空心黑体

背景需求&#xff1a; 【教学类-XX -XX 】20240128名字字卡1.0&#xff08;15CM正方形手工纸、黑体&#xff0c;说明是某个孩子的第几个名字&#xff09;-CSDN博客文章浏览阅读254次&#xff0c;点赞4次&#xff0c;收藏2次。【教学类-XX -XX 】20240128名字字卡1.0&#xff0…

12.Elasticsearch应用(十二)

Elasticsearch应用&#xff08;十二&#xff09; 1.单机ES面临的问题 海量数据存储问题单点故障问题 2.ES集群如何解决上面的问题 海量数据存储解决问题&#xff1a; 将索引库从逻辑上拆分为N个分片&#xff08;Shard&#xff09;&#xff0c;存储到多个节点单点故障问题&a…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之CheckboxGroup组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之CheckboxGroup组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、CheckboxGroup组件 提供多选框组件&#xff0c;通常用于某选项的打开或关…

【python】GtkWindow程序

一、多个GtkWindow 在GTK中&#xff0c;并不推荐使用多个GtkWindow来创建多文档界面&#xff08;MDI&#xff09;&#xff0c;而是推荐使用单个GtkWindow内嵌入的小部件&#xff08;如GtkNotebook&#xff09;来实现类似的效果。然而&#xff0c;如果确实想要创建多个窗口的例…

教育能打破阶层固化吗

中式教育以应试为核心&#xff0c;强调知识的灌输和学生被动接受。随着社会的发展&#xff0c;中式教育的短板逐渐显现&#xff0c;创新能力的缺乏、对记忆的过度依赖、忽视个体差异等问题日益突出。 建议所有大学生都能去看看《上海交通大学生存手册》&#xff0c;它道出了中…

23种设计模式使用场景分析

概述 网上关于设计模式的文章特别多&#xff0c;就不赘述了&#xff0c;我认为在敲代码的时候知道根据当前代码结构选择合适的设计模式是最重要的&#xff0c;知道了要使用哪个设计模式&#xff0c;就可以上网随便百度一下&#xff0c; 简述 对23中设计模式的分类 创建型模式…

日常学习之:vue + django + docker + heroku 对后端项目 / 前后端整体项目进行部署

文章目录 使用 docker 在 heroku 上单独部署 vue 前端使用 docker 在 heroku 上单独部署 django 后端创建 heroku 项目构建 Dockerfile设置 settings.pydatabase静态文件管理安全设置applicaiton & 中间件配置 设置 requirements.txtheroku container 部署应用 前后端分别部…

(自用)learnOpenGL学习总结-高级OpenGL-模板测试

模板测试 模板测试简单来说就是一个mask&#xff0c;根据你的mask来保留或者丢弃片段。 那么可以用来显示什么功能呢&#xff1f;剪切&#xff0c;镂空、透明度等操作。 和深度缓冲的关系是&#xff1a; 先片段着色器&#xff0c;然后进入深度测试&#xff0c;最后加入模板测…

2023年中国工控自动化市场现状及竞争分析,美日占主角,国产品牌初崭头角

工控自动化是一种运用控制理论、仪器仪表理论、计算机和信息技术&#xff0c;对工业生产过程实现检测、控制、优化、调度、管理和决策&#xff0c;达到增加产量、提高质量、降低消耗、确保安全等目的综合性技术。产品应用领域广泛&#xff0c;可分为OEM型行业和项目型行业。 近…

2024年最新 MySQL的下载、安装、启动与停止

一、MySQL的下载 MySQL最常用的2个版本&#xff1a; 社区版&#xff1a;免费开源&#xff0c;自由下载&#xff0c;不提供官方技术支持&#xff0c;大多数普通用户选择这个即可。企业版&#xff1a;需要付费&#xff0c;不能在线下载&#xff0c;可以使用30天&#xff0c;提供…

aio-max-nr达到上限导致数据库性能问题

问题说明&#xff1a; rac数据库节点一表面上看由于归档等待事件导致业务性能问题。 问题分析过程&#xff1a; 查看awr报告top事件&#xff0c;等待事件主要为归档切换问题&#xff1a; 查看事件&#xff0c;归档等待达到20多分钟 检查节点alert日志发现&#xff0c;最…

Linux第37步_解决“Boot interface 6 not supported”之问题

在使用USB OTG将“自己移植的固件”烧写到eMMC中时&#xff0c;串口会输出“Boot interface 6 not supported”&#xff0c;发现很多人踩坑&#xff0c;我也一样。 见下图&#xff1a; 解决办法&#xff1a; 1、打开终端 输入“ls回车”&#xff0c;列出当前目录下所有的文件…

从centos镜像上创建具备SSH链接的Dockerfile

1. 创建目录&#xff0c;名字随意 mkdir dockfile cd dockfile 2. 创建名字为Dockerfile的文件 touch Dockerfile 3. 编辑内容如下 FROM centos MAINTAINER liufeng "liufgeoscene.cn"RUN /bin/echo root:123456|chpasswd RUN useradd test RUN /…