C++ 大数相加 专题课件

一、题目要求

题目描述

普通int、long long整型存储不下百位超长数字,使用字符数组存储数字字符串,手动模拟竖式加法实现大数运算。

样例输入

11111111111111111111
222

样例输出

11111111111111111333

计算原理

11111111111111111111 + 222 = 11111111111111111333

二、完整原始源代码(保留原生换行缩进)

#include<bits/stdc++.h> using namespace std; int main() { char a1[100+1] = {0}; char a2[100+1] = {0}; int a3[100+1] = {0}; int a11[100+1] = {0}; int a22[100+1] = {0}; cin>>a1>>a2; int len1 = strlen(a1); int len2 = strlen(a2); int len3 = len1>len2?len1:len2; len3 += 1; int k = 0; for(int i = 0; i < len3-len1; i++ ) { a11[k++] = 0; } for(int i = 0; i < len1; i++) { a11[k++] = a1[i] - '0'; } k = 0; for(int i = 0; i < len3-len2; i++ ) { a22[k++] = 0; } for(int i = 0; i < len2; i++) { a22[k++] = a2[i] - '0'; } for(int i = len3-1; i >= 1; i--) { //a3[i] = a11[i] + a22[i]; a3[i] = (a11[i] + a22[i])%10; a3[i-1] += (a11[i] + a22[i])/10; } for(int i = 0; i < len3; i++ ) { if(i == 0) { if(a3[0] == 0) { continue; } } cout<<a3[i]; } return 0; }

三、代码分段拆解+逐段详细讲解

【分段1:头文件与基础声明】
#include<bits/stdc++.h> using namespace std;

1. `#include`:万能头文件,一次性包含C++所有常用库,自带`strlen`字符串函数、cin/cout输入输出;
2. `using namespace std;`:标准命名空间,省略`std::cin`、`std::cout`的前缀书写。

【分段2:主函数入口、数组定义】
int main() { // 存储输入的两个大数字符串 char a1[100+1] = {0}; char a2[100+1] = {0}; // 存储加法最终结果 int a3[100+1] = {0}; // 转成纯数字的整型数组(高位补0对齐用) int a11[100+1] = {0}; int a22[100+1] = {0};

1. `char a1/a2[100+1]`:字符数组,最多读取99位大数,+1预留字符串结束符`\0`;初始全部置0;
2. `int a11/a22`:把字符'0'~'9'转换成数字0~9的数组,用于竖式计算;
3. `int a3`:存储相加后的结果数组,同步预留101位空间。

【分段3:读取输入、计算数字长度】
cin>>a1>>a2; int len1 = strlen(a1); int len2 = strlen(a2); // 取两个数字更长的那一个长度 int len3 = len1>len2?len1:len2; len3 += 1; // 额外多1位,预留最高位进位

1. `cin>>a1>>a2`:读取两行输入的两个大数字符串;
2. `strlen()`:统计字符串实际字符个数(数字位数);
3. `len3 = max(len1,len2)+1`:统一对齐长度,+1是为了防止最高位相加产生进位(如999+999=1998,多一位1)。

【分段4:第一个数字a1高位补0,转换为数字数组a11】
int k = 0; // 前面填充0,把短数字拉长到len3位 for(int i = 0; i < len3-len1; i++ ) { a11[k++] = 0; } // 把字符'0'~'9'转成数字0~9存入数组 for(int i = 0; i < len1; i++) { a11[k++] = a1[i] - '0'; }

以样例输入举例:a1长度20,len3=21,先循环填充1个0放在数组最前面,再把20个'1'转成数字1存入;
`字符 - '0'`原理:ASCII码中'0'~'9'连续,减去'0'就能得到对应数值。

k = 0; for(int i = 0; i < len3-len2; i++ ) { a22[k++] = 0; } for(int i = 0; i < len2; i++) { a22[k++] = a2[i] - '0'; }

样例a2长度3,len3=21,先填充18个0在数组高位,再存入2、2、2三个数字;
执行完后a11、a22两个数组长度完全相等,可以逐位对应相加。

【分段6:核心竖式加法、进位处理(程序核心)】
// 从最后一位(个位)向前循环,到第1位停止,第0位存进位 for(int i = len3-1; i >= 1; i--) { // 本位数字 = 两数相加 取余数 a3[i] = (a11[i] + a22[i])%10; // 进位 = 两数相加整除10,加到前一位 a3[i-1] += (a11[i] + a22[i])/10; }

1. 循环从数组末尾(个位)向前遍历,模拟竖式从右往左计算;
2. `%10`:只保留当前位的个位数值;
3. `/10`:算出进位,累加到左边相邻高位;
4. 第0位专门用来存放最终最高位产生的进位。

【分段7:遍历输出结果,跳过开头多余的0】
for(int i = 0; i < len3; i++ ) { // 只跳过数组第0位的前导0,中间的0正常输出 if(i == 0) { if(a3[0] == 0) { continue; } } cout<

1. 数组第0位是预留进位位,多数情况下是0,直接跳过不输出;
2. 从i=1开始依次打印每一位数字,中间出现的0正常输出;
3. `return 0;`:主函数正常结束。

四、代码运行演示(样例代入)

输入数字

a1 = "11111111111111111111" 长度20
a2 = "222" 长度3
len3 = 20 + 1 = 21

数组对齐后

a11:[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
a22:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2]

逐位相加结果

最后三位相加:1+2=3,无进位,其余位保持1,最终输出 11111111111111111333

五、代码优缺点分析

✅ 优点

1. 高位补0对齐思路直观,贴合小学竖式加法逻辑,容易理解;
2. 进位处理逻辑完整,本位取余、进位向前累加;
3. 自动过滤最高位多余前导0,输出格式规范;
4. 数组大小支持最多99位大数,满足常规习题需求。

六、核心知识点总结

1. 大数存储:超长数字超出整型范围,必须使用char字符数组/string存储;
2. 字符转数字:`字符 - '0'` 利用ASCII码差值转换;
3. 对齐技巧:短数字高位补0,统一数组长度简化循环;
4. 竖式进位:从个位向左计算,本位存余数,进位加到左侧高位;
5. 输出处理:过滤最高位无效前导0,保证输出格式正确。