從字符串 "1234" 到整數 1234 的核心算法
原始函數分析
int f(char *s) {
int k = 0;
while (*s)
k = k * 10 + *s++ - '0';
return k; // 原代碼拼寫 retuen
}
逐步執行追蹤:f("1234")
| 步驟 | *s (字符) | ASCII碼 | *s - '0' | k (舊) | k = k*10 + 數字 | s 指向 |
| 1 | '1' | 49 | 1 | 0 | 0×10+1=1 | '2' |
| 2 | '2' | 50 | 2 | 1 | 1×10+2=12 | '3' |
| 3 | '3' | 51 | 3 | 12 | 12×10+3=123 | '4' |
| 4 | '4' | 52 | 4 | 123 | 123×10+4=1234 | '\0' |
| 5 | '\0' | 0 | - | 1234 | 循環結束 | - |
核心技術點解析
- *s 判斷:字符串以
'\0' (ASCII 0) 結尾,作為假值終止循環
- *s++ 運算順序:先取值
*s,再指針後移 s++
- -'0' 技巧:利用 ASCII 碼連續性,
'0'=48, '1'=49...,相減得真實數值
- k*10 左移:相當於十進制左移一位,騰出個位給新數字
完整可運行程序
#include <stdio.h>
#include <string.h>
int str_to_int(const char *s) { // const 防止誤修改
int result = 0;
while (*s) {
if (*s < '0' || *s > '9') // 簡單錯誤檢查
break;
result = result * 10 + (*s - '0');
s++;
}
return result;
}
int main() {
char *test_cases[] = {"1234", "0", "42", "999999", "-123", "12a34"};
int n = sizeof(test_cases) / sizeof(test_cases[0]);
for (int i = 0; i < n; i++) {
printf("str_to_int(\"%s\") = %d\n", test_cases[i], str_to_int(test_cases[i]));
}
return 0;
}
輸出結果
str_to_int("1234") = 1234
str_to_int("0") = 0
str_to_int("42") = 42
str_to_int("999999") = 999999
str_to_int("-123") = 0 // 簡易版不支持負號
str_to_int("12a34") = 12 // 遇非數字停止
工業級實現考慮點
- 溢出檢測:
INT_MAX = 2147483647,需在乘 10 前檢查
- 負號支持:檢查首字符
'-',記錄符號位
- 空白字符跳過:標準
atoi/strtol 忽略前導空格
- 錯誤報告:
strtol 通過 endptr 返回解析結束位置
標準庫替代品
#include <stdlib.h>
int val1 = atoi("1234"); // 簡易,無錯誤檢查
long val2 = strtol("1234", NULL, 10); // 推薦,功能完整
long long val3 = strtoll("1234", NULL, 10); // 64位版本