大数计算C代码逻辑、变量命名及减法函数疑问与简易优化请求
大数加减运算C代码技术分析
代码实现
#include <stdio.h> #include <string.h> #include <stdlib.h> int compare(char* num1, char* num2) { int length1 = strlen(num1); int length2 = strlen(num2); if (length1 < length2) { return 1; } else if (length1 > length2) { return 0; } else { for (int i = 0; i < length1; i++) { if (num1[i] < num2[i]) { return 1; } else if (num1[i] > num2[i]) { return 0; } } } return 0; } void add(char* num1, char* num2, char* result) { int length1 = strlen(num1); int length2 = strlen(num2); int i = length1 - 1; int j = length2 - 1; int k = 0; int up = 0; int sum; while (i >= 0 || j >= 0 || up) { int digit1, digit2; if (i >= 0) { digit1 = num1[i] - '0'; i--; } else { digit1 = 0; } if (j >= 0) { digit2 = num2[j] - '0'; j--; } else { digit2 = 0; } sum = digit1 + digit2 + up; up = sum / 10; result[k++] = (sum % 10) + '0'; } result[k] = '\0'; for (int i = 0, j = k - 1; i < j; i++, j--) { char temp = result[i]; result[i] = result[j]; result[j] = temp; } } void subtract(char* num1, char* num2, char* result) { int length1 = strlen(num1); int length2 = strlen(num2); int borrow = 0, diff; int i = length1 - 1; int j = length2 - 1; int k = 0; while (i >= 0 || j >= 0) { int digit1, digit2; if (i >= 0) { digit1 = num1[i] - '0'; i--; } else { digit1 = 0; } if (j >= 0) { digit2 = num2[j] - '0'; j--; } else { digit2 = 0; } diff = digit1 - digit2 - borrow; if (diff < 0) { diff += 10; borrow = 1; } else { borrow = 0; } result[k++] = diff + '0'; } while (k > 1 && result[k - 1] == '0') { k--; } result[k] = '\0'; for (int i = 0, j = k - 1; i < j; i++, j--) { char temp = result[i]; result[i] = result[j]; result[j] = temp; } } void processLine(char* line) { char num1[100], num2[100], optr, result[101]; sscanf(line, "%[^+-]%c%s", num1, &optr, num2); if (optr == '+') { add(num1, num2, result); } else if (optr == '-') { int isNegative = 0; if (compare(num1, num2)) { isNegative = 1; subtract(num2, num1, result); } else { subtract(num1, num2, result); } if (isNegative) { char tempResult[102]; tempResult[0] = '-'; strcpy(tempResult + 1, result); strcpy(result, tempResult); } } printf("%s\n", result); } int main() { FILE* file = fopen("input.txt", "r"); if (file == 0) { printf("Error opening file."); exit(1); } int n; fscanf(file, "%d", &n); fgetc(file); char line[204]; for (int i = 0; i < n; i++) { if (fgets(line, sizeof(line), file)) { if (line[strlen(line) - 1] == '\n') { line[strlen(line) - 1] = '\0'; } processLine(line); } } fclose(file); return 0; }
技术问询解答
1. 代码逻辑连贯性评估
整体逻辑连贯自然,完整覆盖大数加减运算的核心流程:
- 从
input.txt读取运算次数和每行表达式; - 通过
processLine解析两个大数和运算符; - 加法直接调用
add函数,减法先通过compare判断数的大小,确定运算顺序和结果正负,再调用subtract; - 运算函数从低位到高位逐位计算,处理进位/借位,最后反转结果得到正确顺序。
逻辑链条清晰,每个函数职责明确,符合大数运算的常规实现思路。仅compare函数返回值语义未通过注释明确,但结合上下文不影响理解。
2. 变量命名合理性评判
大部分变量命名高效合理,见名知意:
num1、num2、result、optr、borrow、diff等变量直接对应功能,无需额外解释;- 存在少量可优化命名:比如
add函数中表示进位的up,换成通用术语carry更符合编程共识;标记结果数组位置的k,换成res_pos会更直观。
整体命名风格统一,无歧义,不会增加阅读障碍。
3. subtract函数中diff和borrow的作用
diff:存储当前位的计算结果,是被减数当前位数字减去减数当前位数字,再减去上一位借位后的值。若该值为负,说明当前位不够减,给diff加10得到当前位实际数字,同时标记需向高位借位;若非负,则直接作为当前位结果。borrow:标记是否需要向高位借位,值为1表示上一位已借位,当前位计算要扣除该借位;值为0表示无借位,直接计算即可。每次计算完当前位后,更新borrow状态供下一位使用。
4. 新手简易优化方案
针对编程新手,推荐几个易上手的优化点:
- 变量命名优化:将
add函数中的up改为carry,符合进位通用术语;将各函数中标记结果位置的k改为res_pos,让变量含义更直观。 - 添加注释:给
compare、add、subtract函数添加注释,说明功能、参数含义(比如compare返回1表示num1 < num2,返回0表示num1 >= num2);给关键代码块加单行注释,比如加法进位、减法借位的处理逻辑。 - 简化负数处理:在
processLine的减法分支中,若结果为负,无需临时数组拷贝,直接输出负号加结果,代码更简洁:if (isNegative) { printf("-%s\n", result); return; } printf("%s\n", result);
内容的提问来源于stack exchange,提问作者고예빈
相关产品推荐
相关产品推荐

