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

C語言指標與字串深度解析:從記憶體佈局到標準庫函數手寫實作

     編輯:關於C語言

C語言指標與字串深度解析:從記憶體佈局到標準庫函數手寫實作

指標與字串是 C 語言最核心也最易混淆的主題。本文從取址/取值、指標算術、陣列退化、字串字面值、標準庫函數實作五個維度,配合記憶體圖解與完整代碼,徹底釐清指標與字串的本質關係。

取址 & 取值 & sizeof

int a = 10;
int *p = &a;        // 取址:p 存儲 a 的位址
int val = *p;       // 取值:經由位址讀取值
printf("%p\n", &a); // 印出位址 (16進位)
printf("%zu\n", sizeof(a)); // 4 (int大小)
printf("%zu\n", sizeof(p)); // 8 (64位系統指標大小)

關鍵:& 右邊必須是左值 (有位址的物件);sizeof 編譯期計算,不求值運算式。

指標算術與陣列退化

int arr[5] = {1,2,3,4,5};
int *p = arr;           // 陣列名退化為首元素位址
p[2] == arr[2] == *(p+2) == *(arr+2) // 完全等價
// 遞增指標
p++; // 指向下一個 int (位址 + sizeof(int))
// 陣列名是常量指標:arr = p; // 錯誤!

函式參數:陣列即指標

void func(int a[]) { }      // 等價於
void func(int *a) { }       // 等價於
void func(int a[10]) { }    // 10 被忽略,仍是指標
// 函式內 sizeof(a) 返回指標大小,非陣列大小!
// 必須額外傳遞長度參數

字串本質:以 \0 結尾的 char 陣列

char str1[] = "Hello";      // 長度6 (含\0),可修改
char *str2 = "Hello";       // 指向唯讀字面值區,不可修改
char str3[10] = "Hello";    // 長度10,前6有效,其餘\0
// 字串字面值 "Hello" 編譯器存放在唯讀區,相鄰字面值自動連接
"Hello" "World" == "HelloWorld"

標準庫字串函數手寫實作精選

// strlen
size_t my_strlen(const char *s) {
    size_t len = 0;
    while (*s++) len++;
    return len;
}

// strcpy
char *my_strcpy(char *dest, const char *src) {
    char *ret = dest;
    while ((*dest++ = *src++));
    return ret;
}

// strcmp
int my_strcmp(const char *s1, const char *s2) {
    while (*s1 && *s1 == *s2) { s1++; s2++; }
    return *(unsigned char*)s1 - *(unsigned char*)s2;
}

// strcat
char *my_strcat(char *dest, const char *src) {
    char *ret = dest;
    dest += my_strlen(dest);
    while ((*dest++ = *src++));
    return ret;
}

// strchr
char *my_strchr(const char *s, int c) {
    while (*s && *s != c) s++;
    return (*s == c) ? (char*)s : NULL;
}

// strstr (暴力法)
char *my_strstr(const char *haystack, const char *needle) {
    if (!*needle) return (char*)haystack;
    for (; *haystack; haystack++) {
        const char *h = haystack, *n = needle;
        while (*h && *n && *h == *n) { h++; n++; }
        if (!*n) return (char*)haystack;
    }
    return NULL;
}

字串輸入安全模式

char buf[100];
scanf("%99s", buf);        // 限制寬度防溢位
scanf("%99[^\n]", buf);    // 讀整行 (含空格)
fgets(buf, sizeof(buf), stdin); // 更安全,保留換行符

ASCII 碼表速查 (關鍵區段)

0  NUL    32 SP    64 @    96 `
1  SOH    33 !     65 A    97 a
2  STX    34 "     66 B    98 b
...      ...      ...     ...
9  HT     41 )     73 I    105 i
10 LF     42 *     74 J    106 j
13 CR     47 /     79 O    111 o
27 ESC    58 :     90 Z    122 z
31 US     63 ?     95 _    127 DEL

指標操作記憶體,字串是約定俗成的資料格式。理解「位址、值、類型、長度」四要素關係,才能駕馭 C 語言的靈活與危險。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved