不能直接用int或long long做大整数加法,因为其位宽固定(int约10位、long long约19位),处理百位字符串会溢出或触发未定义行为;必须用字符串模拟竖式加法:对齐末位、逐位相加进位、逆序输出结果。

为什么不能直接用 int 或 long long 做大整数加法
因为 C++ 内置整型有固定位宽,int 通常最多表示 10 位十进制数,long long 也只撑到约 19 位。一旦输入是 100 位的数字字符串(比如 "999...999"),直接转换会溢出甚至触发未定义行为——std::stoll 遇到超长字符串会抛 std::out_of_range,而 atoi 直接截断为 INT_MAX 或 0。
所以必须把数字当字符串处理,模拟手算竖式加法:从末位开始逐位相加、进位、存结果。
如何用字符串模拟竖式加法(核心逻辑)
关键不是“写个类”,而是抓住三件事:对齐、进位、逆序输出。不需要额外库,纯标准 C++ 就够。
- 把两个字符串
a和b看作倒过来的数字(即a[i]对应个位、十位…),用两个指针从末尾往前扫 - 每次取
a[i] - '0'和b[j] - '0'转成数字,加上当前进位carry - 结果模 10 得当前位,除 10 更新
carry;最后别忘了把最高位进位补上 - 结果是逆序生成的,所以用
push_back后再调用std::reverse
示例片段:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
std::string addStrings(const std::string& a, const std::string& b) {
std::string res;
int i = a.size() - 1, j = b.size() - 1, carry = 0;
while (i >= 0 || j >= 0 || carry) {
int x = i >= 0 ? a[i--] - '0' : 0;
int y = j >= 0 ? b[j--] - '0' : 0;
int sum = x + y + carry;
res.push_back('0' + (sum % 10));
carry = sum / 10;
}
std::reverse(res.begin(), res.end());
return res;
}
要注意的边界和坑
常见错误不是算法错,而是漏判边界或类型隐式转换出问题:
- 输入可能为空字符串(
""),需提前返回"0"或按需处理 - 不要用
int存单个数字的 ASCII 值再减'0'——如果误写成a[i] - '0'但i已越界,行为未定义;务必先检查i >= 0 - 进位变量必须是
int(不是bool),因为两数最大 9+9+1=19,进位可能是 1,但逻辑上要支持累加 - 不要用
std::stoi或std::stol尝试部分转换——哪怕只转一位,遇到非数字字符也会抛异常
要不要封装成类?什么时候值得做
如果只是偶尔算一次加法,函数就够了;但若要支持减法、乘法、比较、输入输出流重载,就值得抽一个 BigInt 类。不过注意:
- 别一上来就搞运算符重载,先确保加法在各种长度(0 位、1 位、1000 位)、含前导零(如
"00123")下都稳 - 内部存储建议用
std::vector<int></int>(每位存 0–9),而不是std::string,方便后续实现乘法(避免反复push_back字符) - 去掉前导零的逻辑要单独写,且得处理结果为
"0"的情况(不能全删成空串)
真正麻烦的从来不是加法本身,而是怎么让 BigInt("0") + BigInt("0") 返回 "0" 而不是 "",以及怎么让 BigInt("-123") 的符号逻辑不污染加法主干。这些细节比算法多花三倍调试时间。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










