首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言指針進階:手寫字符串連接函數 stringcat 實現 strcpy/strcat 核心邏輯

     編輯:關於C語言

問題描述

實現字符串連接函數 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]

關鍵細節深度解析

1. `while (*source++) ;` 的精確語義

  • *source++ 等價於 *(source++):取當前指針指向的值,然後指針後移。
  • 循環條件檢查的是取值前的字符。當讀到 '\0' (值為 0/false) 時循環結束,但指針已後移一位,指向 '\0' 後的未知內存。
  • 因此必須 source-- 回退,定位到 '\0' 位置準備覆寫。

2. `*source++ = *dest++` 的副作用順序

  • 右邊 *dest++:讀取 dest 指向字符,dest 後移。
  • 左邊 *source++:將值寫入 source 指向位置,source 後移。
  • 賦值表達式的值是被賦的值(即複製的字符),作為 while 條件判斷。複製 '\0' 時值為 0,循環結束。

3. 缺少結尾 '\0' 的後果

若漏寫 *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 表示截斷
}

標準庫對比與返回值約定

函數簽名返回值用途
strcatchar *strcat(char *dest, const char *src)dest 起始地址鏈式調用:strcat(strcat(a,b),c)
strncatchar *strncat(char *dest, const char *src, size_t n)dest 起始地址限制追加長度,防溢出
本實現char *StringCat(char *source, const char *dest)末尾地址(原代碼)/起始地址(建議)教學演示指針操作本質

建議:返回原始 source 起始地址,符合標準庫慣例,支持鏈式調用。

總結

手寫 StringCat 是掌握 C 指針、字符串表示、內存操作的核心功課。關鍵收穫:

  • 字符串以 '\0' 結束,所有操作圍繞尋找/維護此標記;
  • 指針後移 p++ 的副作用發生在取值之後;
  • 邊界檢查是生產代碼必備,教學代碼常省略但必須知曉;
  • 返回起始地址而非末尾,符合 C 庫設計哲學。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved