指针数组,数组指针、指针函数,函数指针
听到这几个名词不知道大家什么感受,反正我是一脸懵逼,不过我还是比较好学的,在老师的指导下,自己下去也钻研了一下,有一些自己的见解,我想在学习过程中也有童鞋遇到了相同的问题,希望我的总结能给你带来帮助。
首先我们先明确一下这几个概念,知道他们都表示什么,ok,请看:
函数指针:函数指针是指向函数的指针变量。 因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。函数指针有两个用途:调用函数和做函数的参数。
指针函数:指针函数是指带指针的函数,即本质是一个函数。函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。
指针数组:在C语言和C++语言中,数组元素全为指针的数组称为指针数组。
一维指针数组的定义形式为:“类型名 *数组标识符[数组长度]”
数组指针:数组名的指针,即数组首元素地址的指针。即是指向数组的指针。
以上这些来自百度百科,概念还是有些抽象,不知所云,估计还是不知道怎么区分。ok接下来我谈下我的看法。
按照我的理解,不管是函数指针还是指针函数,或者说数组指针、指针数组,我们想看后两个字,这两个字就决定了这个东西的大前提。我们分别来看,对函数指针来说,首先它是一个指针,只不过它比较特殊,是一个指向函数的指针,所以它叫函数指针。说它特殊其实也不特殊,我们可以想一下我们声明×××指针、字符指针等指针,他们是不是代表指向×××的指针、字符的指针,只是我们再定义命名时没有注意,那么这样我们就可以解释函数指针了,指向函数的指针。后边我会用代码再解释一下。那么对于数组指针,我们是不是可以理解了呢?就是指向数组的指针。写道这里,我想起了上一篇博文,数组名,那么他就是一个数组指针。区别了这两个,我们接着来看另外两个,按照我前边说的看后两个字,对于指针函数,首先来说,它是一个函数,对于函数我们比较关心的有两个比较关键的因素,一个是返回值,另一个是参数,这里我们涉及到的就是它的返回值。有人就会问了,那为什么不是参数,这个很好解释,就从参数所处的位置就可以区分出来,好了言归正传,对于指针函数就是说函数的返回值是指针类型的,比如像我们常用的库函数malloc(),就是指针函数。最后我们再说指针数组,前三个我都解释,我想这个聪明大家就可以自己解释,这里我还是在解释一下,所谓指针数组,就是存储指针的数组,至于指针数组是存储什么类型的指针,就要看我们声明什么类型的数组,就像我们声明×××数组,存储×××数组,浮点型数组,存储浮点型数据。从概念上区分了清了,但是我们还是见了具体的东西,你不认识我,我不认识你,接下来我就来解决这个问题
为什么会出现什么指针函数、函数指针等,在这里我们先要再引入c语言的运算符优先级表,这些就是由于运算符的优先级造成的。
c语言运算符优先级表
这里我们只关心[]、()与*的优先级,我们可以从图中很明显的得知[]、()的优先级高于*,因而标识符,就会首先与运算级高的结合,先结合的就决定了它的性质。ok,下来我通过代码解释;请看下边的代码:
测试代码
#include<stdio.h>
/*
**输出两个×××数据的最大值
*/
int Int_Max(int a, int b )
{
return a>b?a:b;
}
/*
**输出两个双精度浮点数的最大值
*/
double Double_Max(double a,double b)
{
return a>b?a:b;
}
/*
**定义一个指针函数
*/
int *Fun_Arry(int x, int y)
{
static int arry3[5]= {0};
int *p;
p = arry3;
return p;
}
/*
**定义两个函数指针,用来间接操作刚才定义的两个函数
*/
int (*function1)(int ,int );
double (*function2)(double ,double );
int main()
{
int a = 1, b = 5; //声明两个×××数据
double c = 3.4, d = 3.6; //声明两个浮点型数据
int arry1[5] = {0}; //声明一个×××数组
int DoubleArry_1[3][2];
int DoubleArry_2[3][3];
int *lp1 = NULL, *lp2 = NULL, *lp3 = NULL, *lp4 = NULL, *lp5 = NULL;
int *arry_2[5] ; //声明一个指针数组,用来保存×××指针
int (*arry_3)[2]; //声明一个数组指针,指向一个数组
int (*arry_4)[5]; //声明一个数组指针,指向一个数组
int (*arry_5)[3][3]; //声明一个数组指针,指向一个数组
/*
**变量arry_3是一个数组指针,它指向一个包含2 个int 类型数据的数组,即数组指针
**并且只能指向有两个int类型数据的数组
*/
arry_3 = DoubleArry_1;
arry_4 = &arry1;
arry_5 = &DoubleArry_2;
/*
**function1和function2是我们之前声明的函数指针,用来指向函数是指针,并且由于function1声明为int型的,所以只能指向返回值为int型的函数,
**那么对于function2函数就只能指向返回值为double型的函数,因而,下边分别让他们分别指向了我之前定义的两个函数。
*/
function1 = Int_Max;
function2 = Double_Max;
/*
**arry_2是一个指针数组,按照我上文说的,那它就是用来保存指针的,
**由于我在这里声明的为×××指针数组,所以,这里我们看到保存了我个×××指针。
*/
arry_2[0] = lp1;
arry_2[1] = lp2;
arry_2[2] = lp3;
arry_2[3] = lp4;
arry_2[4] = lp5;
/*
**为了验证函数指针的正确性,我做了一下测试前两行我用函数名,
**直接调用函数,分别得到×××、浮点型的最大值。
*/
printf("Result of origonal function---->Int_Max = %d\n",Int_Max(a,b));
printf("Result of origonal function---->Double_Max = %f\n",Double_Max(c,d));
printf("----------------------------------------------------------------\n");
printf("Result of Function Pointer ----->Int_Max = %d\n",function1(a, b));
printf("Result of Function Pointer ----->Double_Max = %f\n",function2(c, d));
return 0;
}
运行结果测试图
测试代码中我已经尽可能多的给出了注释,我在这里再重点提一个数组指针,数组指针就是指向数组的指针,注意看代码中我用红色标注的部分,分别声明了三个不同类型的数组指针,arry_3是一个指向两个×××元素的数组的指针,并且对于此指针只能指向有两个×××元素的数组,arry_4是一个指向5个×××元素数组的指针ok,这也将涉及到上一篇博文遗留的一个问题,数组名到底是什么。arry_5是一个指向3行3列的二维数组的指针。ok,定义完了了我们来看后边的赋值,arry_3是一个指向两个×××元素的数组的指针,。然后用它接收了一个二维数组名,是不是有疑问,对于arry_3,不是应该指向一个一维数组吗?怎么把一个二维数组名给它了,首先我来告诉你,这是对的,我的上一篇博文是不是谈到,数组名就是代表一个数组,其保存着该数组的首元素的地址,对于二维数组从存储结构上来看,首元素就是一个一维数组,所以用把二维数组名赋值给arry_3,其本质是将一个一维数组赋并且只有两个×××元素的数组的地址赋值给arry_3,我们接着来看,arry_4,我把一个一维数组的地址给它,这时arry_4就指向了一维数组arry1,再看最后一条,如果要操作二维数组,就要把二维数组名的地址给相同类型的数组指针。ok对于这几个很麻烦的的概念,按照自己理解总结了一下,希望能帮到遇到同样问题的你,最后我在总结一下今天写的以及一些注意事项。
函数指针:就是指向函数的指针。
1、函数名就是函数的入口地址
2、指向函数的指针就是函数指针
使用函数指针是要达到 三同 即:1、函数返回值相同2、参数个数相同3、参数对应的类型相同
3、其他类型的指针均可自增自减,但是对于函数指针不允许自增自减
指针数组:存储指针的数组。
1、 数组中的三值合一:数组名、数组首元素地址、数组名的地址
数组名中保存首元素的地址 《 数组名取地址 代表针对整个数组取地址》
2、数组名取地址代表整个数组的地址 当要接收数组名的地址时就要定义一个数组类型的指针
3、一维数组可以通过一级指针接收数组的地址,达到引用数组并操作数组的目的,
但是二维数组却不能通过定义二级指针来接收数组名,达到引用并操纵数组的目的。始终注意:数组名代表整个数组,然后数组名有值保存了数组首元素的地址
4、对于二维数组,从本质上讲是一个一维数组,但是每个元素是一个数组;
数组指针:就是指向数组的指针。
指针函数:返回指针的函数就是指针函数。