num % radix 得最低位,num /= radix 右移,直到 0。'0' + digit(基數 ≤ 10),或 'A' + digit - 10(基數 > 10)。char* my_itoa(int value, char* buffer, int radix) {
if (radix < 2 || radix > 36) return nullptr;
char* p = buffer;
bool negative = false;
unsigned int uval;
if (value < 0 && radix == 10) {
negative = true;
uval = (unsigned int)(-value);
} else {
uval = (unsigned int)value;
}
// 至少寫入一位(處理 value == 0)
do {
int digit = uval % radix;
*p++ = (digit < 10) ? '0' + digit : 'A' + digit - 10;
uval /= radix;
} while (uval);
if (negative) *p++ = '-';
*p = '\0';
// 反轉
for (char *l = buffer, *r = p - 1; l < r; ++l, --r)
std::swap(*l, *r);
return buffer;
}
+/-。result = result * 10 + (ch - '0')。INT_MAX/10 邊界判斷。int my_atoi(const char* str) {
if (!str) return 0;
while (*str == ' ') ++str; // 跳過空格
int sign = 1;
if (*str == '+' || *str == '-') sign = (*str++ == '-') ? -1 : 1;
long long result = 0; // 用長整型暫存檢測溢出
while (*str >= '0' && *str <= '9') {
result = result * 10 + (*str++ - '0');
if (sign == 1 && result > INT_MAX) return INT_MAX;
if (sign == -1 && -result < INT_MIN) return INT_MIN;
}
return (int)(result * sign);
}
int main() {
char buf[32];
cout << my_itoa(1234, buf, 10) << '\n'; // 1234
cout << my_itoa(-1234, buf, 10) << '\n'; // -1234
cout << my_itoa(255, buf, 16) << '\n'; // FF
cout << my_atoi(" -42") << '\n'; // -42
cout << my_atoi("2147483648") << '\n'; // 2147483647 (飽和)
return 0;
}
| 函數 | 標準庫 | 手寫版優勢 |
|---|---|---|
itoa | 非標準(Windows 有) | 跨平台、可控基數、線程安全(調用者提供緩衝區) |
atoi | 標準 C | 可加溢出保護、錯誤碼返回、支援長整型 |
| 現代替代 | std::to_string / std::stoi (C++11) | 類型安全、異常處理、無緩衝區風險 |
手寫 itoa/atoi 是理解「數值與文本轉換」本質的最佳練習,關鍵點在於位提取順序、字符編碼映射、符號與溢出處理。實際工程建議優先使用 C++11 <string> 標準函數。