一、了解本质
我们先得知道他们各自的本质是什么,对于用汉语描述的名字来说,小技巧是最后一个名词是什么,这个表达式的本质就是什么
例如:
指针数组
指向函数指针数组的指针
那么对于表达式来说是怎样的呢:
int *p[10]; -> 指针数组
int (*p)[10]; -> 数组指针
int (*p)(); -> 函数指针
int (*p[10])(); -> 函数指针数组
int (*(*p)[10])(); -> 指向函数指针数组的指针
表达式中,是根据优先级来识别表达式本质的
二、分析各个表达式
1.指针数组 (是数组,是存放一个指针的数组)
判断下面代码:
int *arr1[10]; -> 指针数组
char *arr2[4]; -> 指针数组
char **arr3[5]; ->二级指针数组
2.数组指针 (是指针)
数组的地址如何储存:
int arr[10] = {0};
int*p1 = &arr;//error 不可将int(*)[10] 强转为 int*
int (*p2)[10] = &arr;//ok
3.函数指针
①先来看一段代码
#include <stdio.h>
void fun(int a)
{
printf("hello world\n");
}
int main()
{
void(*fp)();
fp = &fun;
printf("%#p\n", fun);
printf("%#p\n", &fun);
printf("%#p\n", fp);
(*fp)();
fp();
}
分析一下结果可知,在调用函数时,<函数名>和<&函数名>是完全相同的,即main函数中的 fp=&fun; 也可以改为 fp=fun;
定义函数指针以后,调用函数也有两种方式。
②分析下列代码
(*(void (*)())0)();
void (*signal(int , void(*)(int)))(int);
4.函数指针数组
int (*parr1[10]])();
parr1 先和 [] 结合,说明parr1是数组,数组的内容是什么呢?是 int (*)() 类型的函数指针。
5.指向函数指针数组的指针
指向函数指针数组的指针是一个 指针指针指向一个 数组 ,数组的元素都是 函数指针。
void test(const char* str)
{
printf("%s\n", str);
}
int main()
{
//函数指针pfun
void (*pfun)(const char*) = test;
//函数指针的数组pfunArr
void (*pfunArr[5])(const char* str);
pfunArr[0] = test;
//指向函数指针数组pfunArr的指针ppfunArr
void (*(*ppfunArr)[10])(const char*) = &pfunArr;
return 0;
}