文章目錄
- 前言
- 一、字符指針變量
- 二、數組指針變量
- 2.1 數組指針變量是什么
- 2.2 數組指針變量怎么初始化
- 2.2.1 靜態初始化
- 2.2.2 動態初始化
- 三、二維數組傳參的本質
- 四、函數指針變量
- 4.1 函數指針變量的創建
- 4.2 函數指針變量的使用
- 4.3 typedef關鍵字
- 4.4拓展
- 五、函數指針數組
- 六、轉移表
- 總結
前言
在C語言中,指針一直是一個讓初學者頭疼的話題。它看似復雜難懂,但其實只要掌握了正確的方法,就能輕松駕馭。在之前的兩篇博客中,我們已經對指針有了初步的認識。今天,我們將繼續深入探索指針的更多奧秘。
一、字符指針變量
字符指針變量是用來存儲字符數組(字符串)首地址的變量。它的聲明方式是char *指針變量名;
。例如:
char *str = "Hello, World!";
這里,str
就是一個字符指針變量,它指向了字符串"Hello, World!"的首地址。通過字符指針變量,我們可以對字符串進行操作。比如,printf("%s", str);
就可以輸出整個字符串。
二、數組指針變量
2.1 數組指針變量是什么
數組指針變量是用來存儲數組首地址的變量。它的聲明方式是類型 (*指針變量名)[數組長度];
。例如:
int arr[5] = {1, 2, 3, 4, 5};
int (*p)[5] = &arr;
這里,p
就是一個指向包含5個整數的數組的指針變量。它指向了數組arr
的首地址。通過數組指針變量,我們可以訪問數組中的元素。比如,printf("%d", (*p)[2]);
就可以輸出數組中的第三個元素3。
數組指針變量與普通指針變量的區別在于,數組指針變量指向的是一個數組,而普通指針變量指向的是一個單一的變量或一個字符串。數組指針變量在內存中占用的空間比普通指針變量大,因為它需要存儲整個數組的地址信息。
2.2 數組指針變量怎么初始化
數組指針變量的初始化可以通過以下兩種方式:
2.2.1 靜態初始化
在聲明數組指針變量時,直接將其初始化為一個已知數組的地址。例如:
int arr[5] = {1, 2, 3, 4, 5};
int (*p)[5] = &arr;
這里,p
被初始化為指向數組arr
的首地址。
2.2.2 動態初始化
在程序運行過程中,通過malloc
函數動態分配一個數組,并將數組指針變量初始化為分配的內存地址。例如:
int (*p)[5] = (int (*)[5])malloc(sizeof(int) * 5);
if (p == NULL) {printf("Memory allocation failed\n");exit(1);
}
for (int i = 0; i < 5; i++) {(*p)[i] = i + 1;
}
這里,p
被動態分配了一個包含5個整數的數組,并通過循環初始化了數組中的元素。
三、二維數組傳參的本質
在C語言中,當我們把二維數組作為參數傳遞給函數時,實際上傳遞的是數組首地址。函數接收的是一個指向一維數組的指針。例如:
void printArray(int arr[][3], int rows) {for (int i = 0; i < rows; i++) {for (int j = 0; j < 3; j++) {printf("%d ", arr[i][j]);}printf("\n");}
}
這里,arr
是一個指向包含3個整數的一維數組的指針。通過這種方式,我們可以在函數中操作二維數組。
四、函數指針變量
4.1 函數指針變量的創建
函數指針變量是用來存儲函數地址的變量。它的聲明方式是返回類型 (*指針變量名)(參數列表);
。例如:
int add(int a, int b) {return a + b;
}int (*funcPtr)(int, int) = add;
這里,funcPtr
就是一個指向add
函數的指針變量。通過函數指針變量,我們可以調用函數。比如,printf("%d", (*funcPtr)(1, 2));
就可以輸出3。
4.2 函數指針變量的使用
函數指針變量的使用非常靈活,可以用于多種場景。例如,我們可以根據不同的條件調用不同的函數:
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }int (*funcPtr)(int, int);int choice;
printf("Enter your choice (1 for add, 2 for sub): ");
scanf("%d", &choice);if (choice == 1) {funcPtr = add;
} else if (choice == 2) {funcPtr = sub;
} else {printf("Invalid choice\n");return 1;
}printf("%d\n", (*funcPtr)(5, 3));
這里,根據用戶輸入的選擇,程序會調用add
或sub
函數。
4.3 typedef關鍵字
typedef
關鍵字可以用來為數據類型定義一個別名,包括函數指針類型。例如:
typedef int (*FuncPtr)(int, int);FuncPtr funcPtr = add;
這里,FuncPtr
是int (*funcPtr)(int, int)
的別名。通過typedef
,我們可以簡化函數指針的聲明,使代碼更加清晰易讀。
4.4拓展
兩段來自《C陷阱和缺陷》有趣的代碼
五、函數指針數組
函數指針數組是一個數組,其元素都是函數指針。它的聲明方式是返回類型 (*指針數組名[數組長度])(參數列表);
。例如:
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }
int div(int a, int b) { return a / b; }int (*funcPtrArr[4])(int, int) = {add, sub, mul, div};
這里,funcPtrArr
就是一個包含4個函數指針的數組。通過函數指針數組,我們可以根據不同的條件調用不同的函數。比如:
for (int i = 0; i < 4; i++) {printf("%d ", (*funcPtrArr[i])(4, 2));
}
輸出結果為6 2 8 2。
六、轉移表
轉移表是一種利用函數指針數組實現的控制結構。它根據不同的輸入條件,選擇執行不同的函數。例如,在一個簡單的菜單系統中,我們可以使用轉移表來實現不同的功能選項:
void option1() { printf("Option 1\n"); }
void option2() { printf("Option 2\n"); }
void option3() { printf("Option 3\n"); }void (*transferTable[3])() = {option1, option2, option3};int choice;
printf("Enter your choice (1-3): ");
scanf("%d", &choice);if (choice >= 1 && choice <= 3) {transferTable[choice - 1]();
} else {printf("Invalid choice\n");
}
這里,根據用戶輸入的選擇,程序會調用對應的函數。
總結
通過本篇博客的學習,我們深入理解了字符指針變量、數組指針變量、二維數組傳參的本質、函數指針變量、函數指針數組以及轉移表等指針的高級應用。指針是C語言中非常強大的工具,它能讓我們的程序更加靈活和高效。希望讀者能夠通過不斷地實踐和思考,真正掌握指針的精髓。