C++ long long整型声明方法及输入数值异常代码Bug排查
问题1:C++中long long类型整数的声明方式
C++中声明long long类型(64位有符号整型)有两种等价的标准写法,效果完全一致:
- 简写形式:
long long 变量名;,是日常开发最常用的写法,示例:long long userId; - 完整形式:
long long int 变量名;,和简写形式语义完全相同
如果需要声明无符号64位整型,使用unsigned long long 变量名;即可,取值范围为0~2^64-1。
说明:标准规定long long类型至少占8字节,在绝大多数主流编译环境下,有符号long long的取值范围是-2^63 ~ 2^63-1。
问题2:示例代码Bug定位与原因分析
这段代码共有两类会导致运行异常的问题,分别对应输入异常、结果错误场景:
- 输入格式不匹配,导致读取失败
代码中a、b都定义为int类型,使用cin读取int时,仅识别可选前导负号+连续数字字符,遇到非数字类字符会立刻终止当前读取,同时将输入流标记为错误状态,后续所有读取操作默认失效:- 输入
50.000时,读到小数点.就会停止读取,a只能拿到值50,剩余的.000残留在输入流中,b读取失败,值为未初始化的随机垃圾值 - 输入
50,000时,读到千分位逗号,就会停止读取,a同样只能拿到50,剩余的,000残留在输入流中,b读取失败
- 输入
- 整数运算隐式溢出,导致结果错误
就算输入的是两个合法整数,代码依然可能输出错误结果:C中表达式的求值类型仅由参与运算的操作数类型决定,和赋值目标的类型无关。a和b都是int,因此a*b的运算结果也是int类型,如果两个数的乘积超过当前环境int的取值上限(32位环境下int通常最大为2147483647),会先触发有符号整数溢出(属于C标准定义的未定义行为),之后才会把溢出后的错误int值转换为long long赋值给cost,根本无法得到正确的乘积。
修复参考
如果只需要处理普通整数输入,直接把输入变量定义为long long即可避免运算溢出问题,修复后代码如下:
#include <iostream> using namespace std; int main() { long long a,b; long long cost; cin>>a>>b; cost=a*b; cout<<cost; return 0; }
如果业务场景必须支持50.000(带小数位的金额格式)、50,000(带千分位分隔符的数字格式)这类输入,不能直接用cin读取整型,需要先把输入内容按字符串读入,手动过滤掉.、,这类分隔符后再转换为长整型,否则必然出现读取失败的问题。
内容的提问来源于stack exchange,提问作者امیر مهدی هدایتی
相关产品推荐
相关产品推荐

