在C语言中,准确判断指针的类型对于正确使用指针、避免错误以及理解复杂声明至关重要。以下是系统分析指针类型的方法:
一、基础判断方法
1. 从声明格式判断
指针声明的基本模式是:基类型 * 变量名
int *p; // 指向int的指针
char *pc; // 指向char的指针
float *pf; // 指向float的指针
void *pv; // 无类型指针
2. 使用sizeof测试
通过sizeof可以判断指针指向的数据类型大小:
int arr[5];
int *p = arr;
printf("%zu\n", sizeof(*p)); // 输出4(int的大小),说明p指向int
二、复杂指针类型分析
1. 指针数组 vs 数组指针
- 指针数组:先看
[]再看*
int *ap[5]; // ap是数组,元素是int指针 (指针数组)
- 数组指针:先看
*再看[]
int (*pa)[5]; // pa是指针,指向含5个int的数组 (数组指针)
2. 函数指针分析
int (*fp)(int, float);
// 解析:
// 1. fp被*包围,首先是指针
// 2. 指向函数,参数(int,float),返回int
3. 多级指针分析
int **pp; // 指向int指针的指针
int *(*ap)[5]; // 指向数组(元素为int指针)的指针
三、右左法则(解析复杂声明)
- 从标识符开始
- 先向右看,遇到
)就向左看 - 跳出括号后继续向右向左交替
- 结束于基本类型
示例分析:
int (*(*func)(int))[5];
解析步骤:
func- 开始于标识符(*func)- 是一个指针(*func)(int)- 指向接受int参数的函数*(*func)(int)- 函数返回指针(*(*func)(int))[5]- 返回的指针指向含5个元素的数组int (*(*func)(int))[5]- 数组元素是int
结果:func是指向函数的指针,该函数接受int参数,返回指向含5个int元素的数组的指针
四、实用判断技巧
1. 类型定义法(typedef简化)
typedef int (*FuncPtr)(char); // 定义函数指针类型
FuncPtr fp; // 明显是函数指针
2. 编译器辅助法
int *p[5];
// 使用gcc编译时加-Wall选项,会提示类型信息
3. 打印类型信息(GCC扩展)
printf("%s\n", __builtin_types_compatible_p(typeof(p), int *) ? "int*" : "other");
五、常见指针类型速查表
|
声明形式 |
类型描述 |
解引用结果 |
|
|
指向int的指针 |
int |
|
|
指向int指针的指针 |
int * |
|
|
指向含5个int的数组的指针 |
int[5] |
|
|
含5个int指针的数组 |
int * |
|
|
指向函数的指针(无参返回int) |
int(void) |
|
|
指向函数的指针,函数返回指向int[5]的指针 |
int(*)[5] |
六、动态类型检查技巧
1. 运行时类型判断
void print_type(void *ptr, char type) {
switch(type) {
case 'i': printf("int: %d\n", *(int*)ptr); break;
case 'f': printf("float: %f\n", *(float*)ptr); break;
// 其他类型...
}
}
2. 调试器检查
在GDB等调试器中:
(gdb) ptype variable
七、易错点提醒
- 数组名不是指针:虽然常被转换为指针,但
sizeof(array)会返回整个数组大小 - 函数指针的特殊性:函数指针需要匹配精确的函数签名
- void*的局限性**:void指针不能直接解引用,必须转换为具体类型
- const修饰的位置:
const int *p; // 指向const int的指针
int *const p; // const指针指向int

被折叠的 条评论
为什么被折叠?



