【C++】 算术操作符与数据类型溢出详解


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++

文章目录

  • 💯前言
  • 💯C++ 算术操作符详解
    • 基本算术操作符
    • 整数除法与取模行为
    • 类型转换在算术运算中的作用
    • 自增与自减操作符
  • 💯数值溢出:当值超出类型范围时
    • 数据类型的取值范围
    • 正向与负向溢出
    • 避免数值溢出的方法
  • 💯`char` 类型与 ASCII 表的关系
    • `char` 的本质
    • 如何输出整数值和字符值
    • 示例:`char` 赋值整数与字符
      • `char a = 127` 是否规范?
  • 💯取模操作与负数的处理
    • 取模运算符 `%`
      • 工作机制
      • 规则总结
      • 示例
    • 如何确保结果为正?
  • 💯编程建议
  • 💯小结


在这里插入图片描述


💯前言

  • 在程序设计中,理解算术操作符的机制以及数据类型的行为是至关重要的,尤其是在涉及不同类型的数据运算时。本文深入探讨了 C++ 中的算术操作符、数值溢出和类型转换 的细节,结合实际编程中的典型疑问,为您提供理论与实践相结合的视角。本文将涵盖基本算术操作、类型转换、负数取模、数值溢出,以及字符类型(char)与 ASCII 编码的细节。
    C++ 参考手册
    在这里插入图片描述

💯C++ 算术操作符详解

在这里插入图片描述


基本算术操作符

C++ 提供了一组基本的算术操作符,用于执行常见的数学运算,主要包括:

  • +加法,用于将两个操作数相加。
  • -减法,用于计算两个操作数的差值。
  • *乘法,用于计算两个操作数的积。
  • /除法,用于将第一个操作数除以第二个操作数。
  • %取模,用于计算两个整数的余数。

在这里插入图片描述


整数除法与取模行为

  • 整数除法 (/):当两个操作数都是整数类型时,结果也是整数,小数部分将被舍弃。例如:

    int b = 2;
    double d = 7 / 2;  // 结果是 3,因为小数部分被舍弃
    

    在这里插入图片描述

    在上述代码中,虽然变量 d 被定义为 double 类型,但 72 均为 int 类型,因此 7 / 2 的结果为整数 3,随后赋值给 d,因此 d 的值为 3.0

    对于正确处理浮点结果,至少需要确保一个操作数为浮点类型。例如:

    double d = 7.0 / 2;  // 结果为 3.5,因为 7.0 是 double 类型
    

在这里插入图片描述

  • 取模操作 (%) 只能用于整数类型。
    在这里插入图片描述

  • 如果操作数是浮点数类型,必须使用 <cmath> 库中的 fmod 函数来计算余数。例如:

    #include <cmath>
    double result = fmod(10.5, 3.2);  // 结果是 0.9
    

    在这里插入图片描述


类型转换在算术运算中的作用

在算术运算中,C++ 通常会对不同类型的操作数进行隐式类型转换,以确保运算的精度和一致性。例如:

  • intdouble 进行运算时,int 会被自动提升为 double,然后进行浮点运算。
    double d = 6.0 / 4;  // 结果是 1.5,因为 6.0 是 double,4 被提升为 double
    
    在上述代码中,6.0double 类型,而 4int,C++ 会将 4 隐式提升为 4.0,进而进行浮点除法,最终得到 1.5
    在这里插入图片描述

自增与自减操作符

C++ 中的 ++-- 操作符用于对变量进行自增和自减操作:

  • 前置形式 (++a--a):先对变量的值进行改变,再使用改变后的值。
  • 后置形式 (a++a--):先使用变量的原始值,再对其进行改变。

例如:

int a = 5;
int b = ++a;  // b = 6, a = 6
int c = a++;  // c = 6, a = 7

在这里插入图片描述

在复杂的表达式或循环中,前置与后置自增/自减操作符的使用对结果有很大的影响,因此应当谨慎使用。

在这里插入图片描述


💯数值溢出:当值超出类型范围时

在 C++ 中,数值溢出指的是当计算结果超出变量数据类型所能表示的范围时,结果可能变得无法预测或与预期不符。数值溢出在处理较小的数据类型(如 charshort)时尤为常见。

在这里插入图片描述


数据类型的取值范围

每种数据类型在 C++ 中都有相应的取值范围,这与它们的存储大小直接相关。例如:

  • char 类型:通常占用 1 个字节,有符号的 char 范围为 -128127
  • int 类型:通常占用 4 个字节,范围为 -2,147,483,6482,147,483,647(具体范围取决于编译器和平台)。

当计算结果超出这些取值范围时,便会发生溢出。例如:

#include <iostream>
using namespace std;
int main()
{
	char a = 127;  
	char b = a + 1;  
	cout << (int)b << endl;  //-128
	return 0;
}

在上述代码中,a 的初始值为 char 类型的最大值 127,再加 1 会导致溢出,最终结果从 -128 开始循环。
在这里插入图片描述


正向与负向溢出

  • 正向溢出:当一个有符号类型的值达到最大值再加一时,结果会从最小值重新开始。例如,char a = 127; a += 1; 的结果是 -128
  • 负向溢出:当一个有符号类型的值达到最小值再减一时,结果会从最大值重新开始。例如,char a = -128; a -= 1; 的结果是 127
    在这里插入图片描述

这些现象遵循二进制补码的规则,溢出的结果会在数值范围内循环,这在某些算法中可能导致严重的逻辑错误,特别是在数值计算和边界条件处理时。


避免数值溢出的方法

  • 使用更大的数据类型:如果运算结果可能超出当前类型的范围,应使用更大范围的数据类型,如 longlong long
  • 手动检查溢出风险:在执行运算前,可以对操作数进行判断,以确保不会发生溢出。
  • 使用专门的库或工具:一些库(如 SafeInt)或编译器选项能够检测并避免溢出,从而保障程序的正确性。

在这里插入图片描述


💯char 类型与 ASCII 表的关系

在这里插入图片描述


char 的本质

在 C++ 中,char 类型实际上是一个整数类型,用于存储字符的 ASCII 编码值。char 通常占用 1 个字节,可以表示 -128127(有符号)或 0255(无符号)的整数。

当给 char 赋值一个整数时,实际上是将该整数视为 ASCII 码。例如:

char c = 65;
std::cout << c << std::endl;  // 输出:A

在上述代码中,65 是 ASCII 表中字符 A 的编码,因此输出为 A
在这里插入图片描述


如何输出整数值和字符值

  • 作为字符输出:直接输出 char 类型时,会显示其对应的 ASCII 字符。
  • 作为整数输出:如果希望查看 char 实际存储的整数值,可以将其强制类型转换int
    char c = 'A';
    std::cout << (int)c << std::endl;  // 输出:65
    

在这里插入图片描述


示例:char 赋值整数与字符

考虑以下代码:

char a = 127;
a += 1;
std::cout << (int)a << std::endl;  // 输出:-128

在上述代码中,a 被赋值为整数 127,表示 char 的最大正值。当 a += 1 时,发生溢出,结果为 -128。这是因为 char 类型按照二进制补码表示数值,从最大值溢出到最小值。

在这里插入图片描述


char a = 127 是否规范?

char a = 127; 中,127 是一个整数值,不需要加引号。char 类型存储的是整数值,这个值会在输出时按照 ASCII 编码对应的字符显示。例如,char a = 65; 会输出字符 A。在上述例子中,127char 类型的最大值,当 a += 1 后发生溢出,结果是 -128。因此,直接给 char 赋整数值是合法的,不需要加引号。

在这里插入图片描述


💯取模操作与负数的处理

在这里插入图片描述


取模运算符 %

在 C++ 中,取模运算符 % 用于计算两个整数相除后的余数。然而,当操作数中存在负数时,其行为可能并不符合直觉。
在这里插入图片描述


工作机制

取模运算基于整数除法,通过计算商并求得余数。

  • 具体公式为:a % b = a - (a / b) * b
  • 当有负数时,a / b 的商向零取整,余数的符号由被除数决定。
  • 例如,-7 % 3 中,-7 / 3 的商为 -2(向零取整),余数的计算为:-7 - (-2 * 3) = -7 + 6 = -1
    在这里插入图片描述

规则总结

  • 结果的符号由被除数(左操作数)决定
    • 例如:-7 % 3 的结果是 -1,因为 -7 是负数,结果的符号也为负。
    • 类似地,7 % -3 的结果是 1,因为 7 是正数。
      在这里插入图片描述

示例

int a = -7;
int b = 3;
std::cout << a % b << std::endl;  // 输出:-1

在上述代码中,-7 / 3 的商为 -2(向零取整),余数为 -1。在取模运算中,符号遵循被除数的符号。
在这里插入图片描述


如何确保结果为正?

在某些情况下,我们可能希望取模结果始终为正数,可以使用以下公式来实现:

int result = ((a % b) + b) % b;

这个公式可以确保无论 ab 的符号如何,结果始终为非负值。
在这里插入图片描述


💯编程建议

  • 注意类型范围:在进行加法、乘法等操作时,确保结果不会超出当前数据类型的范围,以避免不必要的溢出。
  • 选择合适的数据类型:根据预期的数据规模选择适合的数据类型(例如 long long 而非 int),以确保结果的正确性。
  • 明确取模运算的行为:特别是在涉及负数时,应仔细理解取模运算的符号规则,必要时通过调整公式来获得预期的结果。
    在这里插入图片描述

💯小结

  1. 在这里插入图片描述
    算术操作符和类型转换:整数运算结果是整数,小数部分会被舍弃,而浮点运算可以保留精度。
  2. 数值溢出:当操作数超出其类型范围时,会发生溢出,结果会按二进制补码规则循环。
  3. char 类型与整数赋值char 本质上是一个整数类型,赋值整数时会存储其对应的 ASCII 码值。
  4. 负数取模:取模结果的符号由被除数决定,负数取模时可能需要调整公式以确保结果为正。

在这里插入图片描述


在这里插入图片描述


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【继承】—— 我与C++的不解之缘(十九)

前言&#xff1a; 面向对象编程语言的三大特性&#xff1a;封装、继承和多态 本篇博客来学习C中的继承&#xff0c;加油&#xff01; 一、什么是继承&#xff1f; ​ 继承(inheritance)机制是⾯向对象程序设计使代码可以复⽤的最重要的⼿段&#xff0c;它允许我们在保持原有类…

使用redis-plus-plus库连接redis

使用redis-plus-plus库连接redis 一、安装redis-plus-plus1.1安装hiredis1.2编译安装redis-plus-plus 二、redis的连接使用2.1创建redis对象2.2向redis中添加元素2.3判断元素是否存在2.4获取元素2.5设置获取过期时间2.6获取类型2.7 删除当前数据库 一、安装redis-plus-plus C …

JMeter 并发策略-针对准点秒杀场景的压测实现

一、场景的压测实现 1&#xff0c;创建线程组&#xff0c;10并发用户执行5次&#xff1b; 2&#xff0c;创建 Synchronizing Timer 元件,用于同步线程&#xff0c;设置同步元件 Synchronizing Timer 3&#xff0c;创建 http 请求4&#xff0c;创建 view results in table 元件…

记一次搞校园网的经历

接教室的校园网&#xff0c;到另一个屋子玩电脑&#xff0c;隔墙想放大一下AP的信号&#xff0c;发现死活不行 这是现状 由于校园网认证的存在&#xff0c;无法用桥接&#xff0c;桥接需要路由器有IP&#xff0c;而这个IP无法用未刷机的路由器来打开校园网页面认证 解决 将一…

打latex公式可以练到像手写一样快吗?

这里分享两个Python Latex工具latexify和handcalcs。 latexify生成LaTeX 数学公式 import math import latexify @latexify.with_latex #调用latexify的装饰器 def solve(a, b, c):return (-b + math.sqrt(b**2 - 4*a*c)) / (2*a)solve 更多例子.......

【Linux】常用命令二

1、cat 用于查看内容较少的纯文本文件。 参数-n可以显示行号。 2、more 用于查看内容较多的纯文本文件。 它会在最下面使用百分比的形式来提示你已经月读了多少内容&#xff0c;你可以使用空格键或回车键向下翻页。 3、head 用于查看纯文本文档的前N行。 4、tail 用于查看…

SolarCube: 高分辨率太阳辐照预测基准数据集

太阳能作为清洁能源在减缓气候变化中的作用日益凸显&#xff0c;其稳定的供应对电网管理至关重要。然而&#xff0c;太阳辐照受云层和天气变化的影响波动较大&#xff0c;给光伏电力的管理带来挑战&#xff0c;尤其是在调度、储能和备用系统管理方面。因此&#xff0c;精确的太…

第三方Express 路由和路由中间件

文章目录 1、Express 应用使用回调函数的参数&#xff1a; request 和 response 对象来处理请求和响应的数据。2、Express路由1.路由方法2.路由路径3.路由处理程序 3. 模块化路由4. Express中间件1.中间件简介2.中间件分类3.自定义中间件 1、Express 应用使用回调函数的参数&am…

nginx+php压测及报错优化

测试环境&#xff1a;虚拟机centos7&#xff0c;nginxphp 压测工具&#xff1a;Apipost 访问的php程序中添加sleep()增加程序执行时长&#xff0c;使用Apipost进行压测&#xff0c;根据服务器配置设置一个大概可能触发报错的并发和轮训次数&#xff0c;若无报错逐渐增加并发和…

探索Python词云库WordCloud的奥秘

文章目录 探索Python词云库WordCloud的奥秘1. 背景介绍&#xff1a;为何选择WordCloud&#xff1f;2. WordCloud库简介3. 安装WordCloud库4. 简单函数使用方法5. 应用场景示例6. 常见Bug及解决方案7. 总结 探索Python词云库WordCloud的奥秘 1. 背景介绍&#xff1a;为何选择Wo…

AOSP的同步问题

repo sync同步时提示出错: error: .repo/manifests/: contains uncommitted changesRepo command failed due to the following UpdateManifestError errors: contains uncommitted changes解决方法&#xff1a; 1、cd 进入.repo/manifests cd .repo/manifests2、执行如下三…

Shell脚本小练习

学习了这么长时间Shell脚本&#xff0c;总得来一次小小的练习吧&#xff0c;那么请看下文&#xff01; 1.用Shell写一个小计算器。 通过read命令获取用户输入的表达式&#xff0c;表达式的格式设定为操作数1 运算符 操作数2&#xff0c;例如53&#xff0c;然后利用设计的脚本…

k8s Init:ImagePullBackOff 的解决方法

kubectl describe po (pod名字) -n kube-system 可查看pod所在的节点信息 例如&#xff1a; kubectl describe po calico-node-2lcxx -n kube-system 执行拉取前先把用到的节点的源换了 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF {"re…

Git 快速入门:全面了解与安装步骤

Git 快速入门&#xff1a;全面了解与安装步骤 一、关于Git 1.1 简介 Git 是一个开源的分布式版本控制系统&#xff0c;由 Linus Torvalds 于 2005 年创建&#xff0c;最初是为了更好地管理 Linux 内核开发而设计。 Git用于跟踪计算机文件的变化&#xff0c;特别是源代码文件…

springboot358智慧社区居家养老健康管理系统(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 智慧社区居家养老健康管理系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&…

探索 IntelliJ IDEA 中 Spring Boot 运行配置

前言 IntelliJ IDEA 作为一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;为 Spring Boot 应用提供了丰富的运行配置选项&#xff0c;定义了如何在 IntelliJ IDEA 中运行 Spring Boot 应用程序&#xff0c;当从主类文件运行应用程序时&#xff0c;IDE 将创建…

快速讲图片中的公式粘贴到word中

只是个人学习记录&#xff0c;不具备教学意义 目的&#xff1a; 比如下面图片中的公式 我们想把这个公式整到我们的word上&#xff0c;传统的方法是通过安装MathType插件&#xff0c;然后慢慢打。我说这样你就慢了。 解决办法&#xff1a; 前提准备&#xff1a; 我们需要…

【STM32+HAL】FreeRTOS学习小札

一、RTOS程序任务结构 如上图所示&#xff0c;在实时操作系统中&#xff0c;开发人员可以把要实现的功能划分为多个任务&#xff0c;每个任务负责实现其中的一部分&#xff0c;每个任务都是一个很简单的程序&#xff0c;通常是一个死循环。 二、多任务系统基本概念 1、FreeRTO…

复杂网络(四)

一、规则网络 孤立节点网络全局耦合网络&#xff08;又称完全网络&#xff09;星型网络一维环二维晶格 编程实践&#xff1a; import networkx as nx import matplotlib.pyplot as pltn 10 #创建孤立节点图 G1 nx.Graph() G1.add_nodes_from(list(range(n))) plt.figure(f…

安规题库;安全测试题;安规刷题;大风车excel

一、电网安规题库、试题 安规真的是年年考&#xff0c;天天背&#xff0c;时不时抽考 往往需要利用上下班的零碎时间来练习和记忆 分享一套电网真题、原题&#xff08;150道选择题&#xff09; 上面的试题&#xff0c;我已经导入到刷题工具&#xff08;大风车excel&#xff…