函数指针 指针函数 数组指针 指针数组 常量指针 指针常量
1. 函数指针(指向函数的指针)
本质:是一个指针变量,专门用来指向函数。函数在内存中占据一块连续空间,其入口地址(函数名代表的地址)可被指针存储,通过该指针可间接调用函数。
定义格式:返回值类型 (*指针变量名)(参数列表);(*与指针名必须用括号括起,否则会被解析为函数声明)
示例:
#include <stdio.h>
int add(int a, int b) { return a + b; }
int main() {
int (*p)(int, int); // 定义函数指针p,指向返回int、参数为两个int的函数
p = add; // 函数名add是地址,赋值给p
printf("%d\n", p(2, 3)); // 通过指针调用函数,输出5
return 0;
}
2. 指针函数(返回值为指针的函数)
本质:是一个函数,其返回值类型为指针。重点是 “函数”,只是返回值是指针变量。
定义格式:返回值类型* 函数名(参数列表);(无括号,*属于返回值类型)
示例:
#include <stdio.h>
#include <stdlib.h>
int* createArray(int n) { // 指针函数:返回int*类型
int* arr = (int*)malloc(n * sizeof(int));
return arr;
}
int main() {
int* ptr = createArray(5); // 接收函数返回的指针
free(ptr);
return 0;
}
3. 数组指针(指向数组的指针)
本质:是一个指针变量,专门指向整个数组(而非数组元素)。指针的类型与数组的类型一致(包括元素类型和数组长度)。
定义格式:元素类型 (*指针变量名)[数组长度];(*与指针名用括号括起,否则会被解析为指针数组)
示例:
#include <stdio.h>
int main() {
int arr[3] = {1, 2, 3};
int (*p)[3]; // 数组指针p,指向“int[3]”类型的数组
p = &arr; // 取整个数组的地址(与arr不同,arr是首元素地址)
// 访问数组元素:通过指针解引用得到数组,再取下标
printf("%d\n", (*p)[0]); // 输出1
return 0;
}
4. 指针数组(元素为指针的数组)
本质:是一个数组,其每个元素都是指针变量。重点是 “数组”,数组的元素类型为指针。
定义格式:元素类型* 数组名[数组长度];(无括号,[]优先级高于*,先形成数组,元素为指针)
示例:
#include <stdio.h>
int main() {
int a = 1, b = 2, c = 3;
int* arr[3] = {&a, &b, &c}; // 指针数组:每个元素是int*
// 访问元素:数组元素是指针,解引用得到值
printf("%d\n", *arr[0]); // 输出1
return 0;
}
(常见用途:存储字符串地址,如char* strs[] = {"abc", "def"};)
5. 常量指针(指向常量的指针)
本质:是一个指针,指向的内容是常量(不可通过指针修改),但指针本身可以指向其他地址。核心:保护指向的内容不被修改。
定义格式:const 元素类型* 指针变量名; 或 元素类型 const* 指针变量名;(const修饰的是 “指向的内容”)
示例:
#include <stdio.h>
int main() {
int a = 10;
const int* p = &a; // 常量指针p,指向a
// *p = 20; // 错误:不能通过p修改指向的内容
p = NULL; // 正确:指针本身可以改变指向
return 0;
}
6. 指针常量(指针本身是常量)
本质:是一个常量,指针的指向不可改变(必须初始化),但指向的内容可以修改。核心:指针的地址是固定的。
定义格式:元素类型* const 指针变量名 = 初始地址;(const修饰的是 “指针变量本身”,必须初始化)
示例:
#include <stdio.h>
int main() {
int a = 10, b = 20;
int* const p = &a; // 指针常量p,初始化指向a
*p = 30; // 正确:可以修改指向的内容(a变为30)
// p = &b; // 错误:指针的指向不能改变
return 0;
}
总结:区分关键
函数指针 vs 指针函数:看核心是 “指针” 还是 “函数”。函数指针是指针(指向函数),指针函数是函数(返回指针)。
数组指针 vs 指针数组:看[]和*的优先级。(*p)[n]是数组指针(先*后[]),*p[n]是指针数组(先[]后*)。
常量指针 vs 指针常量:看const修饰谁。const int* p(修饰*p,内容不可改),int* const p(修饰p,指向不可改)。