C语言为什么会发⽣数据溢出?如何避免数据溢出?

一、问题

cpp 复制代码
有以下程序:

#include <stdio.h>
int main()
{
    int i, sum; /*声明变量 */
    i = 2147483647; /*定义变量*/
    sum = i + 1; /*变量值加1*/
    printf("%d,%d", i, sum); /*输出结果*/
    return 0;
}

运⾏后 sum 的结果是什么?

二、解答

1、分析

按正常的计算,sum 应该是2147483648,但是运⾏后 sum 的结果是-2147483648。这是什么原因呢?

在C语⾔中可以使⽤各种类型的标识符,但是C语⾔标准⾥并没有规定这些类型的具体⻓度,要由各个C编译系统⾃⼰规定。⼀般以⼀个机器字存放⼀个 int 数据,早期的计算机字⻓⼀般为16 位,故以16 位存放⼀个整数,整数的范围在-32768~32767 之间,整数范围太⼩,在使⽤的时候就容易产⽣溢出现象。

在这段代码中,变量i被初始化为2147483647,这是一个int类型的最大值。当执行i+1时,由于int类型的取值范围是-2147483648到2147483647,因此i+1会产生溢出,结果不是预期的2147483648,而是-2147483648。

但现代的计算机⼀般都为32 位以上,以 32 位存放⼀个整数,范围可达±2.1×10^9,所以当前⼀般将 int 和 long 都定义为32 位。在写程序时,要了解所⽤系统对标识符长度的规定,以免出现上⾯的错误。

如果真的产⽣"溢出",运⾏时也不会报错,⽽是将结果从"头"开始计算,即是上⾯的运⾏结果-327682147483648,这与编程者的原意不同。由于系统不会给出"出错信息",所以要靠程序员的细⼼和经验来进⾏排错。

cpp 复制代码
说明:
    当前⼤多编译器多将 int 规定为32 位,所以⼀般不会出现"溢出"现象。

2、解决⽅法

将数据定义为⻓整型long 类型,在输出的时候使⽤"%ld"即可。

cpp 复制代码
注意:
    long 型数据可以得到⼤范围的整数,但同时会降低运算速度。因此,除⾮不得已,否则不要随便
使⽤ long 型。

三、总结

C语⾔数值数据类型都有⼀个取值范围。在进⾏数值运算的时候,有时会因数值超出了定义类型的取值范围⽽产⽣溢出的情况。所以在表⽰数据时,应根据需要选择适当的数据类型。

相关推荐
卡提西亚1 天前
一本通网站1130:找第一个只出现一次的字符
数据结构·c++·笔记·算法·一本通
luoganttcc1 天前
DiffusionVLA 与BridgeVLA 相比 在 精度和成功率和效率上 有什么 优势
人工智能·算法
CoovallyAIHub1 天前
注意力机制不再计算相似性?清华北大新研究让ViT转向“找差异”,效果出奇制胜
深度学习·算法·计算机视觉
CoovallyAIHub1 天前
从图像导数到边缘检测:探索Sobel与Scharr算子的原理与实践
深度学习·算法·计算机视觉
蒙奇D索大1 天前
【算法】递归算法的深度实践:深度优先搜索(DFS)从原理到LeetCode实战
c语言·笔记·学习·算法·leetcode·深度优先
一匹电信狗1 天前
【C++11】右值引用+移动语义+完美转发
服务器·c++·算法·leetcode·小程序·stl·visual studio
jz_ddk1 天前
[实战] 卡尔曼滤波原理与实现(GITHUB 优秀库解读)
算法·github·信号处理·kalman filter·卡尔曼滤波
啊吧怪不啊吧1 天前
一维前缀和与二维前缀和算法介绍及使用
数据结构·算法
草莓熊Lotso1 天前
《算法闯关指南:优选算法--位运算》--36.两个整数之和,37.只出现一次的数字 ||
开发语言·c++·算法
铭哥的编程日记1 天前
深入浅出蓝桥杯:算法基础概念与实战应用(一)基础算法(上)
算法·职场和发展·蓝桥杯