第28课 - 函数与指针分析
- 函数类型
(1) C语言中的函数有自己特定的类型。
(2) 函数的类型由返回值、参数类型和参数个数共同决定。
eg:
int add(int i, int j)的类型为:int(int, int),三个位置都一样才是一样的函数。
(3) C语言中通过typedef为函数类型重命名:
typedef type name(parameter list);
eg:
typedef int f(int, int);
- 函数指针
(1) 函数指针用于指向一个函数。
(2) 函数名是执行函数体的入口地址。
(3) 可通过函数类型定义函数指针: FuncType* pointer;
(4) 也可以直接定义:type (* pointer) (parameter list);
pointer为函数指针变量名,type为指向函数的返回值类型,parameter list为指向函数的参数类型列表。
(5) 函数名取不取&,没有区别,与数组名不同。
实例分析--函数指针的本质与使用
#include <stdio.h>
typedef int(FUNC)(int);
int test(int i)
{
return i * i;
}
void f()
{
printf("Call f()... ");
}
int main()
{
FUNC* pt = test; //函数名就是一个地址
void(*pf)() = &f; //用偷懒的方式定义了函数指针,对于函数指针,有&和没有它,最后//的效果是一样的,也就是说,上面两种函数指针的初始化方式是一样的。
pf();
(*pf)();
printf("Function pointer call: %d ", pt(2)); //等价于直接调用test()函数。
}
运行结果:
Call f<>...
Call f<>...
Function pointer call:4
- 回调函数
(1) 回调函数是利用函数指针实现的一种函数调用机制。
(2) 回调机制原理:
① 调用者不知具体事件发生的时候需要调用的具体函数。
② 被调函数不知何时被调用,只知道被调用后需要完成的任务。
③ 当具体事件发生时,调用者通过函数指针调用具体函数。
(3) 回调机制的将调用者和被调函数分开,两者互不依赖。
回调函数的使用示例:
#include <stdio.h>
typedef int(*FUNCTION)(int);
int g(int n, FUNCTION f) //f是个函数指针
{
int i = 0;
int ret = 0;
for(i=1; i<=n; i++)
{
ret += i*f(i); //从1开始的累加求和函数
}
return ret;
}
int f1(int x)
{
return x + 1;
}
int f2(int x)
{
return 2*x - 1;
}
int f3(int x)
{
return -x;
}
int main()
{
printf("x * f1(x): %d ", g(3, f1)); //这种方式也被称为注册,将f1注册给g
printf("x * f2(x): %d ", g(3, f2));
printf("x * f3(x): %d ", g(3, f3));
}
运行结果:
x * f1(x):20
x * f2(x):22
x * f3(x):-14
自我总结:我们发现所谓的回调函数就是将几个有重复的函数进行拆分,将不重复的部分和重复的部分分开,进行重新组合,已达到提高效率、减少代码的作用。
指针阅读技巧解析
左右法则
(1) 从最里层的圆括号中未定义的标示符看起
(2) 首先往右看,再往左看
(3) 当遇到圆括号或者方括号时可以确定部分类型,并调转方向,把它提取出来。
(4) 重复(2)(3)步骤,直到阅读结束
下面我们用该法则分析一下下面的程序:
#include <stdio.h>
int main()
{
int (*p2)(int*, int (*f)(int*));
/*
从p2开始看,p2是个指针指向一个函数,返回值是int,参数分别是int*和另一个函数指针类型。另一个函数指针f的返回值类型是int,参数是int*。
*/
int (*p3[5])(int*);
/*
从p3开始,p3是一个包含5个元素的数组。再往下看这是一个指针,一个函数指针。返回值是int型,参数是int*型。
*/
int (*(*p4)[5])(int*);
/*
从p4开始,这是一个指针。把它拿出来变成int (*[5])(int*); p4指向数组,数组指针,有5个元素,每个元素又是指针,指向函数。函数的返回值是int型,参数是int*型。
数组指针是个指针,指针数组是个数组。看最后面。
*/
int (*(*p5)(int*))[5];
/*
int (*(*p5)(int*))[5];——p5是个指针,指向一个具有一个int *型形参的函数,这个函数返回一个指向具有5个int元素的数组的指针。可以从内向外扒开一会,又可以从外向内扒开一会。
*/
}