#include <stdio.h>

// void (*fun)(void) = &fun//函数指针
// void *fun(void){return 指针}//指针函数 					 				因为优先级变了 
//void (*fun(void/int/char op))(void){return 函数指针;}//函数指针作为返回值	

//1.
typedef int (*PTR)[3];//把int (*)[3] 换为 PTR 
//2.
typedef void (*PTR_FUN)(void);//定义函数指针类型,满足返回值和参数都是void
							  //相当于 void (*fun)(void) = &fun1;
							  //但省去了两个void 和 * ,只需要PTR_FUN fun = &fun1;
//typedef int* (*PTR_ARRAY)(int);//和上面一样,只是换了个返回值变成了指针 
//3. 
//typedef void (*PTR_FUN_FUN)(int);//其实和上面定义类似 
//void(*funA(int, void (*funB)(int)))(int);
//			||
//void(*funA(参数))(int);//★★★:*funA后面还跟了参数列表,所以返回值是函数指针,参数列表中的funB也是函数指针,
//★★★:所以是一个参数为一个int和一个函数指针,返回值为函数指针的函数  
PTR_FUN funC(int n,PTR_FUN);
PTR_FUN funC(int n,PTR_FUN funCptr)//调用哪个函数,调用几次,最后返回调用的函数指针 
{	
	for(int i = 0;i<n;i++)
		(*funCptr)();
	return funCptr;
}

void fun1(void)
{
	printf("fun1调用成功\n");
}
void fun2(void)
{
	printf("fun2调用成功\n");
} 



int main()
{	//1.
	printf("1.***********************************\n");
	int array[3] = {1,2,3};
	PTR ptr = &array;//取地址,相当于1行3列的二维数组 
	for(int i=0;i<3;i++)
		printf("%d\n",(*ptr)[i]);
	//2.
	printf("2.***********************************\n");
	PTR_FUN ptr_fun1 = &fun1;//相当于 void (*fun)(void) = &fun1; 
	(*ptr_fun1)();
	PTR_FUN ptr_fun2 = &fun2;
	(*ptr_fun2)();
	//!!!!!!!!!!!!!!!!!!!!!!!!!! 
	PTR_FUN ptrfun[2]={&fun1,&fun2};//相当于数组,只不过是函数指针类型的数组,函数又是双void类型的 
	for(int i=0;i<2;i++)
		(*ptrfun[i])();//注意和1行n列数组一样
					   //如:(*p)(),(*p)[],因为[]和()都比*优先级高,所以要加上括号确保先解引用 
	//3.
	printf("3.***********************************\n");
	funC(3,ptrfun[1]);
	
	return 0;
}