實現字符串連接函數 StringCat(char *source, const char *dest),將 dest 內容追加到 source 末尾。要求純指針操作,不使用標準庫 strcat,深度理解 C 字符串以 '\0' 結束的本質與指針算術。
#include <stdio.h>
#define MAX 100
char *StringCat(char *source, const char *dest);
int main() {
char s1[MAX] = "I LOVE ";
char *s2 = "C++ and C language!";
StringCat(s1, s2);
printf("%s\n", s1); // 輸出: I LOVE C++ and C language!
return 0;
}
char *StringCat(char *source, const char *dest) {
// 1. 移動 source 到字符串末尾 (\0 處)
while (*source++) ; // 空語句體,指針後移直到指向 \0
source--; // 回退一步,指向 \0 位置
// 2. 逐字符複製 dest 到 source 末尾
while (*dest != '\0') { // 等價於 while (*dest)
*source++ = *dest++; // 複製字符並同步後移兩指針
}
*source = '\0'; // 關鍵:補上新的結束符
return source; // 通常返回原 source 起始地址,鏈式調用
}
初始狀態:
source → [I][ ][L][O][V][E][ ][\0][?][?]...
dest → [C][+][+][ ][a][n][d]...[\0]
步驟1: while(*source++) ;
source 移動到 \0 後一位: [I][ ][L][O][V][E][ ][\0]←source [?]...
步驟2: source--;
source 回退指向 \0: [I][ ][L][O][V][E][ ][←source\0][?]...
步驟3: while(*dest) *source++ = *dest++;
依次複製 'C','+','+',' ',... 並同步後移
直到複製 '\0' 結束
最終:
source起始 → [I][ ][L][O][V][E][ ][C][+][+][ ][a][n][d]...[\0]
*source++ 等價於 *(source++):取當前指針指向的值,然後指針後移。source-- 回退,定位到 '\0' 位置準備覆寫。*dest++:讀取 dest 指向字符,dest 後移。*source++:將值寫入 source 指向位置,source 後移。若漏寫 *source = '\0';(雖然循環已複製 '\0',但 source 已後移),新字符串可能缺少結束符,導致 printf 越界讀取、緩衝區溢出風險。
char *StringCat_Safe(char *source, size_t src_size, const char *dest) {
char *orig = source;
size_t len = 0;
// 1. 計算 source 當前長度
while (len < src_size && *source) { source++; len++; }
if (len == src_size) return NULL; // 無結束符,非法輸入
// 2. 追加 dest,檢查邊界
while (*dest && len + 1 < src_size) { // +1 留給 \0
*source++ = *dest++;
len++;
}
*source = '\0';
return (len < src_size) ? orig : NULL; // 返回 NULL 表示截斷
}
| 函數 | 簽名 | 返回值 | 用途 |
|---|---|---|---|
| strcat | char *strcat(char *dest, const char *src) | dest 起始地址 | 鏈式調用:strcat(strcat(a,b),c) |
| strncat | char *strncat(char *dest, const char *src, size_t n) | dest 起始地址 | 限制追加長度,防溢出 |
| 本實現 | char *StringCat(char *source, const char *dest) | 末尾地址(原代碼)/起始地址(建議) | 教學演示指針操作本質 |
建議:返回原始 source 起始地址,符合標準庫慣例,支持鏈式調用。
手寫 StringCat 是掌握 C 指針、字符串表示、內存操作的核心功課。關鍵收穫:
p++ 的副作用發生在取值之後;