浅析指针数组、数组指针、函数指针、函数指针数组、指向函数指针的数组的指针

1.指针数组
首先它是一个数组,数组的元素都是指针,数组占多少字节由数组本身决定,它是“储存指针的数组”的简称。                        例如int *arr1[10];是一个具有10个元素的数组,每个元素均为指向一个整型的指针。

2.数组指针
  
   首先它是一个指针,它指向一个数组。在32位系统下永远是占4字节,至于它指向数组占多少字节并不重要。它是“指向数组的指针”简称。
例如:int *p1[10];
          int (*p2)[10];

在这里先需要明白一个符号之间的优先级问题。”()”的优先级是最高的,下来是”[ ]”,再下来是”*“
int *p1[10]:可以理解为先与[10]结合,就是一个数组p1,然后是和”int*“结合,就表示数组中的内容全部都是int*类型的,所以这就是一个指针数组,数组中包含的是10个指向int类型数据的指针。所以它就是一个指针数组。
int (*p2)[10]:这里“()”的优先级比“[]”高,“*”号和p2构成一个指针的定义,指针变量名为p2,int修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。那现在我们清楚p2是一个指针,它指向一个包含10个int类型数据的数组,即数组指针。

3.函数指针

   函数指针就是函数的指针。它是一个指针,指向一个函数。

  例如:char *fun3(char *p1,char *p2);
  这里函数名为fun3,两个char* 类型的形参p1p2,其类型是char *型,函数返回值char *型。
  char * *fun2(char *p1,char *p2);
  这里函数名为fun2,两个char 类型的形参 p1p2,与上一个唯一的差别是函数返回值char **型,二级指针。
  char *(*fun1)(char * p1,char *p2);
  这里我们就可以用优先级来进行判断,它先于()结合,可以知道 fun1 是一个指针,然后它指向的是一个函数。而这个函数呢,就是有两个 char* 类型的形参 p1 p2 ,函数返回值 char* 的函数。
两个有趣的代码
//代码1  
(*(void (*) ()) 0) ();  
  
简析: void(*) ();    // 为函数指针类型,没有参数,没有返回值  
           (void (*) ()) 0;    //将0强制转换为函数指针类型,0是一个地址,也就是说一个函数保存在首地址为0的一段区域内。
           (*(void (*) ()) 0);    //解引用0地址开始的一段内存里面的内容,其内容就是保存在首地址为0的一段区域内的函数。
           (*(void (*) ()) 0) ();    //函数调用
  
//代码2  
void (*signal (int, void(*)(int) ) ) (int);  
简析:  
signal (int, void(*)(int) );    //signal()为一个函数,有两个参数,参数类型:一个整型,一个函数指针,该函数指针指向int参数,返回voi

 4.函数指针数组

函数指针数组:它是一个数组,这个数组中的元素就是我们前面所提到的函数指针。
char ** p[3](char*p);
上面这个就是一个函数指针数组,首先它是有3个元素的一个数组,里面存放的是指向函数的指针,这些指针指向一些返回值类型为指向字符的指针,参数为一个指向字符的指针的函数。


5.指向函数指针的数组的指针

首先给出一个函数指针的数组的指针
char ***p[3])(char *p);
在这里,首先按照优先级从个最里面看,最里面的(*p)这是一个指针。
* *p[3])这个说了这个指针是指向含有三个元素的数组的指针。
char* **p[3])(char *p)这个说了这个数组中存放的元素是3个函数指针,这些指针指向一些返回值为指向字符的指针。然后这个函数的参数是指向字符的指针。
总结:
1. 指针数组是数组:内部元素都是“指针”
2.数组指针是指针:存放“数组”的地址
3.函数指针是指针:存放“函数”的地址
4.函数指针数组是数组:内部元素都是“函数指针”
5.指向函数指针数组的指针是指针:存放“函数指针数组”的地址

猜你喜欢

转载自blog.csdn.net/qq_41268108/article/details/80489702
今日推荐