数据类型的溢出

1. 如何自己计算得到边界值


注:整数常量的数据类型默认为:能表示该数的最小数据类型。
以下从小到大排列,选择表中能够表示该整数常量的第一个数据类型(如 8 选 int,2^32+10 选 long int)
- 10进制常量可选:int, long int, long long int
- 8进制或16进制常量可选:int, unsigned int,long int,unsigned long int, long long int,unsigned long long int)

// 计算数据类型的边界:最小值和最大值
//
#include <iostream>
using namespace std;
int main()
{
    //计算无符号整型
    unsigned int uint_max, uint_min;
    uint_max = ~(unsigned)0;//按位取反
    uint_min = 0;
    cout <<"uint_max = " << uint_max << endl;
    cout <<"uint_min = " << uint_min << endl;
    //计算有符号整型
    int int_max, int_min;
    int_max = (~(unsigned)0 >> 1) ;
    int_min = -int_max - 1;
    cout <<"int_max = "<< int_max << endl;
    cout <<"int_min = "<< int_min << endl;
}

2. C/C++库文件的数据类型边界

在C语言中的各数据类型的边界如下:
包含在头文件#include <limits.h>
c++包含在#include <limits> – 引用的是limits.h的内容

//limits.h
#define MB_LEN_MAX    5             /* max. # bytes in multibyte char */
#define SHRT_MIN    (-32768)        /* minimum (signed) short value */
#define SHRT_MAX      32767         /* maximum (signed) short value */
#define USHRT_MAX     0xffff        /* maximum unsigned short value */
#define INT_MIN     (-2147483647 - 1) /* minimum (signed) int value */
#define INT_MAX       2147483647    /* maximum (signed) int value */
#define UINT_MAX      0xffffffff    /* maximum unsigned int value */
#define LONG_MIN    (-2147483647L - 1) /* minimum (signed) long value */
#define LONG_MAX      2147483647L   /* maximum (signed) long value */
#define ULONG_MAX     0xffffffffUL  /* maximum unsigned long value */
#define LLONG_MAX     9223372036854775807i64       /* maximum signed long long int value */
#define LLONG_MIN   (-9223372036854775807i64 - 1)  /* minimum signed long long int value */
#define ULLONG_MAX    0xffffffffffffffffui64       /* maximum unsigned long long int value */

3. 如何判读溢出

参考传送门:
C语言的整型溢出问题:http://www.kuqin.com/shuoit/20140421/339376.html

#include <limits.h>
//有符号整型的判断溢出
void f(signed int si_a, signed int si_b) {
    signed int sum;

    /* Handle error */
    if (((si_b > 0) && (si_a > (INT_MAX - si_b))) ||
        ((si_b < 0) && (si_a < (INT_MIN - si_b)))) {

        return;
    }

    sum = si_a + si_b;
}
### C语言中的数据类型溢出及其处理 #### 整型溢出问题概述 在C语言中,当数值超出给定类型的表示范围时会发生整型溢出。例如,在32位系统上`int`通常占用4字节,其有效范围是从-2,147,483,648到2,147,483,647;而无符号整数则从0到4,294,967,295。一旦超过这个界限,就会发生环绕现象[^3]。 #### 检测与预防措施 为了防止潜在的安全风险和逻辑错误,开发者应当采取适当的方法来检测并避免这种情况的发生: - **边界检查**:编程过程中应始终考虑可能的最大最小值,并加入必要的条件判断语句以确保不会越界。 - **使用更大容量的数据类型**:如果预计会有非常大的数字参与运算,则可以选择更宽泛的类型如`long long int`或采用高精度库来进行计算。 - **编译器警告选项**:启用GCC等编译工具提供的所有可用诊断标志(比如-Wall),它们可以帮助识别可能导致溢出的情况。 - **运行期防护机制**:利用现代操作系统和服务端框架所提供的保护特性,像ASLR地址空间布局随机化技术可以增加攻击者预测内存位置难度,降低因缓冲区过载引发的危害程度。 #### 编码实践建议 下面给出一段改进后的代码片段用于说明如何安全地读入用户输入而不造成任何形式上的溢出隐患: ```c #include <stdio.h> #include <limits.h> // 定义最大允许值 #define MAX_SAFE_VALUE LLONG_MAX / 3LL int main(void){ long long n; // 输入前先提示用户注意合理范围内的数值 printf("Please enter an integer less than or equal to %lld:\n",MAX_SAFE_VALUE); // 使用%lld格式符匹配long long 类型变量 if(scanf("%lld",&n)!=1 || n>MAX_SAFE_VALUE||n<1){ fprintf(stderr,"Invalid input.\n"); return EXIT_FAILURE; } int count=0; while(n!=1){ ++count; if((n&1)==1){ // 判断奇偶性的优化方式 if(n>(LLONG_MAX-1)/3L){ fprintf(stderr,"%lld * 3 + 1 would overflow!\n",n); break ; } n=n*3+1; }else{ n>>=1; // 等价于除二操作但效率更高 } } printf("Count=%d\n",count); return EXIT_SUCCESS; } ``` 这段程序不仅限定了合理的输入区间还加入了额外的验证环节用来阻止非法状态下的继续执行流程,从而有效地规避了可能出现的各种异常状况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值