字串比較函數實作
#include
#include
int string_compare(const char *str1, const char *str2) {
assert(str1 != NULL);
assert(str2 != NULL);
while (*str1 == *str2) {
if (*str1 == '\0') return 0; // 完全相等
str1++;
str2++;
}
return *str1 - *str2; // 返回第一個不同字元的 ASCII 差值
}
int main() {
char *arr[2];
arr[0] = "ab";
arr[1] = "a";
printf("%d\n", string_compare(arr[0], arr[1])); // 輸出 'b' - '\0' = 98 > 0
return 0;
}
演算法關鍵點
- 逐字元比對:同步推進兩指標
- 早期退出:首個差異即返回,不掃描剩餘
- 差值語意:< 0 表示 str1 < str2,> 0 表示 str1 > str2,= 0 相等
- 標準庫對應:行為等同
strcmp
指標陣列 vs 陣列指標:核心區別
宣告語法對比
int *ptr_arr[10]; // 指標陣列:10 個 int* 元素
int (*arr_ptr)[10]; // 陣列指標:指向「10 個 int 的陣列」的指標
優先級解析
優先級 (高→低):
1. () 括號
2. [] 陣列下標
3. * 指標宣告/解參考
分析:
int *ptr_arr[10]; → int * (ptr_arr[10]) → (int*)[10] → 指標陣列
int (*arr_ptr)[10]; → int (*arr_ptr)[10] → int(*)[10] → 陣列指標
記憶體佈局與用法差異
| 特性 | 指標陣列 int *p[3] | 陣列指標 int (*p)[3] |
| 實體內容 | 3 個指標 (各 4/8 bytes) | 1 個指標 (4/8 bytes) |
| 指向目標 | 各自指向不同 int/陣列 | 指向一個包含 3 int 的陣列 |
| 初始化 | int a,b,c; p[0]=&a; p[1]=&b; p[2]=&c; | int arr[3]; p=&arr; |
| 解參考 | *p[i] 取第 i 個指向的值 | (*p)[i] 取目標陣列第 i 個值 |
| sizeof | 3 * sizeof(int*) | sizeof(int*) |
| 典型用途 | 字串陣列 char *argv[]、多態物件表 | 二維陣列函數參數 void f(int (*a)[N]) |
實戰場景對比
場景 1:字串排序 (指標陣列)
char *names[] = {"Zhang", "Li", "Wang", "Chen"};
// 排序時只交換指標,不移動字串內容
for (int i=0; i<3; i++)
for (int j=0; j<3-i; j++)
if (strcmp(names[j], names[j+1]) > 0) {
char *tmp = names[j];
names[j] = names[j+1];
names[j+1] = tmp;
}
場景 2:矩陣運算 (陣列指標)
void print_matrix(int (*mat)[4], int rows) {
for (int i=0; i
常見錯誤與避坑
| 錯誤代碼 | 問題 | 修正 |
int *p[3] = {{1,2},{3,4},{5,6}}; | 指標陣列無法直接用巢狀初始化 | 需先定義陣列再取址 |
void f(int *p[3]) { p[0][1]=5; } | 參數實為 int**,非二維陣列 | 用 void f(int (*p)[3]) 或 void f(int p[][3]) |
sizeof(p) 用於參數陣列 | 參數退化為指標,sizeof 為指標大小 | 需額外傳遞維度參數 |
結語
字串比較 以雙指標同步掃描、早期退出、差值返回為核心邏輯,是 strcmp、memcmp 等標準函數的基石。指標陣列 vs 陣列指標 是 C 語言型別系統中最易混淆也最關鍵的區別:前者是「指標的容器」,後者是「陣列的導航器」。精通宣告優先級解析法、記憶體佈局差異、函數參數退化規則,即能在字串處理、矩陣運算、多態介面設計中精準選型、避開陷阱。
- 上一篇文章: C 語言實作克魯斯克爾演算法:最小生成樹完整程式碼與邊界標記法優化
- 下一篇文章: C 語言陣列存取等價性:a[i] ≡ i[a] ≡ *(a+i) 核心原理與實證
Copyright ©
程式碼之家 All Rights Reserved