// 原代碼關鍵錯誤片段
s[k] = s1[i--] + s2[j--] - '0' + t; // 錯誤:字符相加邏輯錯誤
t = s[k] > '9'; // 錯誤:進位判斷錯誤
if (t) s[k] -= 10; // 錯誤:ASCII 碼直接減 10 不能得到正確字符
'5' + '3' = 106 (ASCII),非數值 8。必須先 - '0' 轉數值,運算後 + '0' 轉字符'9' 無意義,應比較數值 > 9'9' + 1 = ':',減 10 得到 '/',非 '0'#include
#include
void str_add(const char *a, const char *b, char *result) {
int len_a = strlen(a), len_b = strlen(b);
int max_len = (len_a > len_b) ? len_a : len_b;
int carry = 0;
int idx = 0;
// 從個位開始(字符串末尾)
for (int i = len_a - 1, j = len_b - 1; i >= 0 || j >= 0 || carry; i--, j--, idx++) {
int digit_a = (i >= 0) ? a[i] - '0' : 0;
int digit_b = (j >= 0) ? b[j] - '0' : 0;
int sum = digit_a + digit_b + carry;
result[idx] = (sum % 10) + '0'; // 存個位字符
carry = sum / 10; // 進位
}
result[idx] = '\0';
// 反轉結果(當前是低位在前)
for (int i = 0, j = idx - 1; i < j; i++, j--) {
char tmp = result[i];
result[i] = result[j];
result[j] = tmp;
}
}
// 測試
int main() {
char a[] = "99999999999999999999";
char b[] = "1";
char res[100];
str_add(a, b, res);
printf("%s + %s = %s\n", a, b, res); // 輸出: 100000000000000000000
return 0;
}
void str_sub(const char *a, const char *b, char *result) {
int len_a = strlen(a), len_b = strlen(b);
int borrow = 0;
int idx = 0;
for (int i = len_a - 1, j = len_b - 1; i >= 0; i--, j--) {
int digit_a = a[i] - '0';
int digit_b = (j >= 0) ? b[j] - '0' : 0;
int diff = digit_a - digit_b - borrow;
if (diff < 0) {
diff += 10;
borrow = 1;
} else {
borrow = 0;
}
result[idx++] = diff + '0';
}
result[idx] = '\0';
// 反轉並去除前導零
for (int i = 0, j = idx - 1; i < j; i++, j--) {
char tmp = result[i];
result[i] = result[j];
result[j] = tmp;
}
// 去除前導零
char *p = result;
while (*p == '0' && *(p+1) != '\0') p++;
if (p != result) memmove(result, p, strlen(p) + 1);
}
| 步驟 | 錯誤寫法 | 正確寫法 | 原理 |
|---|---|---|---|
| 字符轉數值 | 直接相加 | c - '0' | ASCII '0'=48, '1'=49... |
| 數值運算 | 字符比較 | 整數加減乘除 | 數學運算在數值域 |
| 進位/借位 | > '9' | > 9 / < 0 | 數值域判斷 |
| 結果存字符 | ASCII 直接改 | digit + '0' | 數值轉字符 |
| 結果順序 | 正序存 | 逆序存再反轉 | 從個位開始算 |
int compare_str_num(const char *a, const char *b) {
int la = strlen(a), lb = strlen(b);
if (la != lb) return la - lb;
return strcmp(a, b); // 同長度字典序即數值序
}
int main() {
char s1[100], s2[100], res[101];
scanf("%s %s", s1, s2);
printf("%s + %s = ", s1, s2);
str_add(s1, s2, res);
printf("%s\n", res);
printf("%s - %s = ", s1, s2);
if (compare_str_num(s1, s2) >= 0) {
str_sub(s1, s2, res);
} else {
str_sub(s2, s1, res);
printf("-");
}
printf("%s\n", res);
return 0;
}
字符串大整數運算核心:**字符↔數值轉換正確、逆序計算、進位借位邏輯清晰、結果反轉輸出**。原代碼在字符域直接運算導致邏輯全錯。掌握「數值域計算、字符域存儲」這一原則,加減乘除大整數皆可舉一反三。