前言:为了更好熟悉C语言,列出部分重要内容。承前所述,对各位编程大咖来说,属于小菜一碟,不值一提。文笔水平有限,若能对初级编程者起到一点启示就算不错。对自己而言,只为了加深记忆。
指针是C语言最精髓的部分,也是最复杂的部分。函数是C语言的基本组成模块,通过函数的调用和组合组成了整个程序,比如通常认为函数的作用在计算产生新数据,函数形参在传递数据。两者的组合---函数指针,将指向函数的指针传递给函数。初学时候对有的概念比较模糊很容易弄错,借几个小函数来对函数指针的思路进行整理。
/*函数指针的定义和用法*/
#include<stdio.h>
int Add(int x, int y);
int MUL(int x, int y);
int (*cacul)(int x, int y); //声明函数指针
typedef int (*backage)(int x, int y); //声明函数指针的另一种写法
void x_ptr(backage x, char n); //函数指针可以表示成数据类型 函数○1
void creatFunc_ptr(backage newFunc); //用函数指针生成一个新函数 函数○2
int cac_ptr(int(*fp)(int x,int y),int x,int y); //函数指针做形参的写法,返回值类型+
(不能是函数指针原型的函数指针)+(函数中其他变量) 函数○3
int Add(int x, int y)
{
int result_ADD;
result_ADD = x + y;
return result_ADD;
}
int MUL(int x, int y)
{
int result_MUL;
result_MUL = x * y;
return result_MUL;
}
int newFunc(int x, int y) //函数○4
{
int result;
result = x + y * 2 - 10;
return result;
}
void x_ptr(backage x, char n) //函数○1
{
int i;
for (i = 0; i < n; i++)
printf("%p\n", x);
}
int cac_ptr(int(*fp)(int x, int y),int x,int y) //函数○3
{
return (*fp)(x, y);
}
void creatFunc_ptr(backage newFunc) //函数○2
{
printf("the newFunc address is %p\n", newFunc);
}
int main(void)
{
cacul = Add;
printf("%d\n",cac_ptr(cacul, 3, 5));
printf("%d\n", cac_ptr(MUL, 3, 5));
x_ptr(cacul, 3);
x_ptr(MUL, 3);
printf("%d\n", newFunc(2, 10));
creatFunc_ptr(newFunc);
creatFunc_ptr(&newFunc);
}
声明函数Add和MUL,再声明了两个指向函数的指针backage和cacul(两者是一样的作用)
1.函数指针可以在函数形参中作数据类型---函数o1;
主函数中调用函数o1时,传入了两个函数Add和MUL:x_ptr(cacul, 3); x_ptr(MUL, 3);相当于是两个函数的地址。
2.函数指针可用于构造新函数---定义函数o2,生成函数o4
所生成函数o4类型是由定义决定的,int (*cacul)(int x, int y);函数指针只关心返回值类型和形参数据类型和个数,构造的函数需与之保持一致。注意这里的函数o2没有实质作用,由它生成了函数o4.函数指针作数据类型时,引入一个函数,这个函数可以是已有的,也可以是尚未定义的。在这里是后者,可以据此生成一个新的函数即本例中的o4
引申:我们知道函数计算数据,传入数据,理论上讲可以用一个函数建立起整个程序---方法:在函数形参中嵌套函数指针,使之生成新的函数。
3.函数指针作为函数形参的写法---函数o3
本例中:int(*fp)(int x,int y),和第2点有所不同,这里是整个函数指针作形参,包括了返回值类型和形参类型及个数。如上所述,函数指针只关心返回值类型和形参数据类型及个数,在形参中把这几点表示出来(真正的形参是(*fp))。回忆指针的表示两个要素:指针类型及指向的数据地址。与之对比函数指针只要把指针类型表示出来就可以了。函数o3的功能是把函数指针指向的函数重现出来。或许有人会问:为什么要搞这么复杂,直接调用原来的函数不就行了吗?这个问题留待以后再解释。
4.调用使用函数指针做形参的函数时,可以传入函数指针,也可以传入函数名。
这点与字符串类似,字符串是指向自身的指针,函数名也可以看作指向自身的指针。在基础部分,C语言的设计者对这点做了兼容,既然函数名也是地址,那么作为函数指针传入也是可以的。在主函数中调用cac_ptr和x_ptr都体现了这点。当使用传入函数指针的方法时,需事先指向函数:
cacul = Add;
printf("%d\n",cac_ptr(cacul, 3, 5));
而creatFunc_ptr(newFunc);这句也表示了新创建的函数newFunc作为指向自身的指针传入,不然的话用creatFunc_ptr(&newFunc);也可以,两者结果是一样的。
小结:函数声明;函数指针声明 ;函数指针作数据类型的使用;函数指针作函数形参的使用。