標準庫 <string.h> 提供的字串函數雖方便,但理解其底層實作能深化指標與記憶體操作功力。本文完整實作 9 個核心字串函數,含詳細註解與邊界處理。
strRev(XOR 交換法)void strRev(char *str) {
assert(str != NULL);
char *end = str + strlen(str) - 1;
while (end > str) {
*str ^= *end;
*end ^= *str;
*str ^= *end;
str++; end--;
}
}
使用 XOR 交換無需暫存變數,展示位運算技巧。
strcpychar *strcpy(char *dest, const char *src) {
assert(dest && src);
char *ret = dest;
while ((*dest++ = *src++));
return ret;
}
返回原始目的地址支援鏈式呼叫。
strcatchar *strcat(char *dest, const char *src) {
assert(dest && src);
char *ret = dest;
dest += strlen(dest); // 移至結尾
while ((*dest++ = *src++));
return ret;
}
strcmpint strcmp(const char *s1, const char *s2) {
assert(s1 && s2);
while (*s1 && *s1 == *s2) { s1++; s2++; }
return *(unsigned char *)s1 - *(unsigned char *)s2;
}
返回差值:<0, =0, >0 對應小於、等於、大於。
strlensize_t strlen(const char *str) {
assert(str);
size_t len = 0;
while (*str++) len++;
return len;
}
atoi(健壯版)int atoi(const char *str) {
assert(str);
int sign = 1, val = 0, started = 0;
while (*str) {
if (!started && (*str == '+' || *str == '-' || isdigit(*str))) {
started = 1;
if (*str == '-') { sign = -1; str++; continue; }
if (*str == '+') { str++; continue; }
}
if (!isdigit(*str)) break; // 或報錯
val = val * 10 + (*str++ - '0');
}
return sign * val;
}
itoachar *itoa(int num) {
static char buf[12]; // 足夠 32 位整數含符號
int i = 0, neg = 0;
if (num == 0) { buf[i++] = '0'; }
else {
if (num < 0) { neg = 1; num = -num; }
while (num) { buf[i++] = '0' + num % 10; num /= 10; }
if (neg) buf[i++] = '-';
}
buf[i] = '\0';
// 反轉
for (int l = 0, r = i - 1; l < r; l++, r--) {
char t = buf[l]; buf[l] = buf[r]; buf[r] = t;
}
return buf;
}
countVowelint isVowel(char c) {
c = toupper(c);
return (c=='A'||c=='E'||c=='I'||c=='O'||c=='U');
}
int countVowel(const char *str) {
int cnt = 0;
while (*str) if (isVowel(*str++)) cnt++;
return cnt;
}
isPalindrome(忽略非字母)int isPalindrome(const char *str) {
int len = strlen(str);
for (int i = 0, j = len - 1; i < j; i++, j--) {
while (i < j && !isalpha(str[i])) i++;
while (i < j && !isalpha(str[j])) j--;
if (toupper(str[i]) != toupper(str[j])) return 0;
}
return 1;
}
const 正確性與 assert 防禦性程式設計++, +=)是核心操作dest 使函數可串接(如 strcat(strcpy(buf, "A"), "B"))親手實作標準庫函數,是從「會用 API」進階到「懂底層」的最佳途徑。