C语言不踩坑: 自动类型转换规则

news2025/1/15 16:36:39

先看一个例程:

# include <stdio.h>
int main(void)
{
    int a = -10;
    unsigned b = 5;
    if ((a+b) > 0)
    {
        printf("(a+b) > 0\n");
        printf("(a+b) = %d\n",a+b);
    }
    else
    {
    	printf("(a+b) <= 0\n");
	}
    return 0;
}

运行的结果是:

(a+b) > 0
(a+b) = -5

看完这个结果会产生疑问:-10+5不是小于0的吗?怎么会在判断的时候大于0,而且打印值的时候也显示就是-5。

这是因为有个自动转换的规则:有符号整型和无符号整型混合运算时,有符号型自动转换成无符号型,运算的结果是无符号的。
在判断(a+b)>0时,由于b是无符号整型,而a是有符号整型,因此a会变成无符号整型则变成一个很大的数再与b相加,结果还是很大的正数,所以判断大于0。

为什么里面打印a+b的值时却是正常的-5呢?首先我们要知道加法的计算机底层逻辑其实是按位相加,得到的结果数同样的内存数据,翻译成有符号数和无符号数都可以,a+b的结果-5从内存里看,与一个很大的无符号数的内存数据是一样的,前面判断(a+b)>0时,是按-5的内存数据无符号状态去和0比,后面打印结果时,用的是%d打印的是按有符号数据输出,即使a+b的结果是一个很大的无符号数,但按有符号看待的话结果就出来-5。
所以那是被%d输出符号影响了,换个C++程序再看:

#include <iostream>
 
int main()
{
    int a = -10;
    unsigned int b=5;
    std::cout << a+b;
    return 0;
}

结果是:
在这里插入图片描述

这个题目告诉我们,平时写代码时,要注意运算式中是否有不同类型数混合,因尽量避免不确定性,最好用强制类型转换注明,否则可能会产生意外的结果。

如果参与运算的数据类型不同,会自动转化为同一类型再运算。这就是自动转换。
自动转换的规则如下:

  1. 当参与运算的数据的类型不同时,编译系统会自动先将它们转换成同一类型,然后再进行运算。

但问题是转换的时候是谁转换成谁呢?转换的基本规则是“按数据长度增加的方向进行转换”,以保证精度不降低。比如 int 型数据和 long 型数据进行相加或相减运算时,系统会先将 int 型数据转换成 long 型,然后再进行运算。这样的话运算结果的精度就不会降低。

long 是“大水桶”,int 是“小水桶”。int 能存放的,long 肯定能存放;而 long 能存放的,int 不一定能存放。

  1. 所有的浮点运算都是以双精度进行的。

在运算时,程序中所有的 float 型数据全部都会先转换成 double 型。即使只有一个 float 型数据,也会先转换成 double 型,然后再进行运算。为什么要这样呢?因为 CPU 在运算的时候有“字节对齐”的要求,这样运算的速度是最快的。

  1. char 型和 short 型数据参与运算时,必须先转换成 int 型。这也是涉及 CPU 的运行原理的。

  2. 有符号整型和无符号整型混合运算时,有符号型要转换成无符号型,运算的结果是无符号的。

  3. 整型和浮点型混合运算时,整型先转换成浮点型,运算的结果是浮点型。
    (2)(3)(4)(5)四条规则总结起来,当类型混合运算时,按如下级别转换:

doublefloatlongunsignedintcharshort
  1. 在赋值运算中,当赋值号两边的数据类型不同时,右边的类型会转换为左边的类型,然后再赋给左边。如果右边数据类型的长度比左边长,那么将会丢失数据,这样就会降低精度,所以编译的时候会产生警告。如果右边精度低于左边,则输出正常计算结果。
    比如:
    int a;
    float b=9.9;
    float c=2.2;
    a=b+c;//a结果是12
    这个过程是9.9和2.2先转成double进行运算得到12.1。然后再转换为左边的int型,即只取整数。

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

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

相关文章

svn 分支(branch)和标签(tag)管理

版本控制的一大功能是可以隔离变化在某个开发线上&#xff0c;这个开发线就是分支&#xff08;branch&#xff09;。分支通常用于开发新功能&#xff0c;而不会影响主干的开发。也就是说分支上的代码的编译错误、bug不会对主干&#xff08;trunk&#xff09;产生影响。然后等分…

实现echarts主题随项目主题切换

前言 项目中很多时候都带有dark/light两中主题类型&#xff0c;通过switch标签控制&#xff0c;但是echarts图形是通过canvas标签绘制&#xff0c;其背景颜色和字体样式并不会随着项目主题类型的切换而切换。所以需要额外设置监听主题事件&#xff0c;主要实现思路如下&#x…

【LeetCode】982. 按位与为零的三元组

982. 按位与为零的三元组 题目描述 给你一个整数数组 nums &#xff0c;返回其中 按位与三元组 的数目。 按位与三元组 是由下标 (i, j, k) 组成的三元组&#xff0c;并满足下述全部条件&#xff1a; 0 < i < nums.length0 < j < nums.length0 < k < num…

深度学习笔记:数据正规化和抑制过拟合

1 Batch-normalization batch-normalization将输入数据转化为平均值0&#xff0c;标准差为1的分布&#xff0c;该方法可以加速学习并抑制过拟合。batch-normalization作为神经网络特定的一个层出现 batch-normalization计算表达式&#xff1a; 接下来&#xff0c;会对数据进…

tmux 使用看这一篇文章就够了

tmux简介及用途 tmux是一个终端复用工具&#xff0c;允许用户在一个终端会话中同时管理多个终端窗口&#xff0c;提高了终端使用效率&#xff0c;尤其在服务器上进行远程管理时更加实用。在tmux中&#xff0c;可以创建多个终端窗口和窗格&#xff0c;并在这些窗口和窗格之间自…

八、Bean的生命周期

Bean生命周期的管理&#xff0c;可以参考Spring的源码&#xff1a;AbstractAutowireCapableBeanFactory类的doCreateBean()方法。 1 什么是Bean的生命周期 Spring其实就是一个管理Bean对象的工厂。它负责对象的创建&#xff0c;对象的销毁等。 所谓的生命周期就是&#xff1a…

【SpringCloud】SpringCloud教程之Feign实战

目录前言SpringCloud Feign远程服务调用一.需求二.两个服务的yml配置和访问路径三.使用RestTemplate远程调用(order服务内编写)四.构建Feign(order服务内配置)五.自定义Feign配置(order服务内配置)六.Feign配置日志(oder服务内配置)七.Feign调优(order服务内配置)八.抽离Feign前…

论文投稿指南——中文核心期刊推荐(新闻事业)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

Spring Cloud融合Nacos配置加载优先级 | Spring Cloud 8

一、前言 Spring Cloud Alibaba Nacos Config 目前提供了三种配置能力从 Nacos 拉取相关的配置&#xff1a; A&#xff1a;通过内部相关规则(应用名、扩展名、profiles)自动生成相关的 Data Id 配置B&#xff1a;通过 spring.cloud.nacos.config.extension-configs的方式支持…

Redis十大类型——List常见操作

Redis十大类型——List常见操作 底层数据结构是双端链表 Redis列表是字符串值的链接列表。Redis列表经常用于&#xff1a; 实现堆栈和队列。为后台工作系统构建队列管理。 命令操作简列 lpush &#xff1a; 左侧添加元素rpush &#xff1a; 右侧添加元素lrange &#xff1a; …

LPNet for Image Derain

Lightweight Pyramid Networks for Image Deraining前置知识高斯-拉普拉斯金字塔图像中的高频信息和低频信息为什么高斯-拉普拉斯金字塔可以实现去雨&#xff1f;可能性分析网络结构整体结构&#xff1a;子网结构&#xff1a;递归块结构&#xff1a;后续补充代码 前置知识 这…

数组--java--动态数组--有序数组--底层

java数组基础--java中的数组创建数组空间占用初始化数组访问元素插入查找删除元素动态数组扩容插入和添加重写toString删除二维数组二维数组注意点有序数组实现测试写在开头&#xff1a; 这篇文章包括数组的基础、一点底层的内容和一些稍微深入的东西。 作为第一个深入学习的数…

【2021.12.25】ctf逆向中常见加密算法和编码识别

【2021.12.25】ctf逆向中常见加密算法和编码识别&#xff08;含exe及wp&#xff09; 文章目录【2021.12.25】ctf逆向中常见加密算法和编码识别&#xff08;含exe及wp&#xff09;0、前言1、基础加密手法2、base64&#xff08;1&#xff09;原理&#xff1a;&#xff08;2&#…

利用出厂状态下的闲置主机配置HP M1136打印机

利用出厂状态下的闲置主机配置HP M1136打印机 打印机型号&#xff1a;LaserJet M1136 MFP 主机状态&#xff1a;出厂状态&#xff0c;C盘及储存盘被分成了5片 网络环境&#xff1a;与打印机相连的主机全程无Internet连接&#xff0c;主机处于离线状态。打印机驱动及一些相关软…

Splunk 成功获取Salesforce 数据

1: 先说一下Splunk server 上要安装Splunk Add-on for Salesforce : (https://splunkbase.splunk.com/) 去下载: https://splunkbase.splunk.com/app/3549 2: 下载安装后,看到如下界面: 3: 官方的指导文档: Configure your Salesforce account to collect data…

0301_对应的南京比特物联网

0301_对应的南京比特物联网目录概述需求&#xff1a;设计思路实现思路分析1.流程拓展实现性能参数测试&#xff1a;参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better …

C#的Version类型值与SQL Server中二进制binary类型转换

使用C#语言编写的应用程序可以通过.NET Framework框架提供的Version类来控制每次发布的版本号&#xff0c;以便更好控制每次版本更新迭代。 版本号由两到四个组件组成&#xff1a;主要、次要、内部版本和修订。 版本号的格式如下所示&#xff0c; 可选组件显示在方括号 ([ 和…

UML 时序图

时序图&#xff08;Sequence Diagram&#xff09;是显示对象之间交互的图&#xff0c;是按时间顺序排列的。 时序图中显示的是参与交互的对象及其对象之间消息交互的顺序。 时序图包括的建模元素主要有&#xff1a;对象&#xff08;Actor&#xff09;、生命线&#xff08;Lif…

项目实战典型案例19——临时解决方案和最终解决方案

临时解决方案和最终解决方案一&#xff1a;背景介绍二&#xff1a;思路&方案四&#xff1a;总结五&#xff1a;升华一&#xff1a;背景介绍 本篇博客是对项目开发中出现的临时解决方案和最终解决方案进行的总结和改进。目的是将经历转变为自己的经验。通过博客的方式分享给…

(蓝桥真题)最长不下降子序列(权值线段树)

样例输入&#xff1a; 5 1 1 4 2 8 5 样例输出&#xff1a; 4 分析&#xff1a;看到这种对其中连续k个数进行修改的我们就应该想到答案是由三部分组成&#xff0c;因为求的是最长不下降子序列&#xff0c;那么我们可以找到一个最合适的断点i&#xff0c;使得答案是由区间[1…