指標是 C 語言靈魂。本文系統梳理指標運算、const 修飾語義、動態記憶體管理、標準字串函數手寫實現,建立扎實底層功力。
void swap(int *a, int *b)。minmax(arr, len, &min, &max))。int divide(int a, int b, int *res) 返回成功/失敗,結果經指標回傳。const Struct *。| 宣告 | 含義 | 可修改 |
|---|---|---|
const int *p / int const *p | 指向常量整數 | p (指標), *p (值) 不可 |
int *const p | 常量指標 (指標本身不可變) | *p (值), p 不可 |
const int *const p | 雙重常量 | p, *p 均不可 |
判斷口訣:**const 在 * 右邊修飾指標,左邊修飾值**。
p + 1:地址增加 sizeof(*p),指向下一個同類型元素。p - q:返回元素個數差 (型別為 ptrdiff_t)。*p++:取值後指標後移 (後綴 ++ 優先級高於 *)。#include <stdlib.h>
void *malloc(size_t size); // 分配 size 字節,未初始化
void *calloc(size_t n, size_t sz); // 分配 n*sz 並歸零
void *realloc(void *ptr, size_t size); // 調整大小
void free(void *ptr); // 釋放,ptr 必須來自 malloc 系
if (!p) handle_error();。malloc 對應一個 free。free(p); p = NULL; 避免懸空指標二次釋放。free(p+2) 崩潰。size_t my_strlen(const char *s) {
size_t len = 0;
while (s[len]) len++;
return len;
}
int my_strcmp(const char *s1, const char *s2) {
while (*s1 && *s1 == *s2) { s1++; s2++; }
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
}
char *my_strcpy(char *dest, const char *src) {
char *ret = dest;
while ((*dest++ = *src++)); // 包含 '\0'
return ret;
}
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 *h, const char *n) {
if (!*n) return (char*)h;
for (; *h; h++)
if (*h == *n) {
const char *a=h, *b=n;
while (*a && *a==*b) { a++; b++; }
if (!*b) return (char*)h;
}
return NULL;
}
char *my_strcat(char *dest, const char *src) {
char *d = dest;
while (*d) d++; // 找尾部
while ((*d++ = *src++));
return dest;
}
int getchar(void):讀一字元,EOF (-1) 表示結束 (Unix Ctrl+D, Windows Ctrl+Z)。int putchar(int c):寫一字元。gets** (無邊界檢查),用 fgets(buf, sizeof(buf), stdin)。