C语言-第28课 - 函数与指针分析

第28课 - 函数与指针分析

  1. 函数类型

(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. 函数指针

(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()...\n");

}

int main()

{

    FUNC* pt = test; //函数名就是一个地址

    void(*pf)() = &f; //用偷懒的方式定义了函数指针,对于函数指针,有&和没有它,最后//的效果是一样的,也就是说,上面两种函数指针的初始化方式是一样的。

    pf();

    (*pf)();

        printf("Function pointer call: %d\n", pt(2));  //等价于直接调用test()函数。

}

运行结果:

Call f<>...

Call f<>...

Function pointer call:4

  1. 回调函数

(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\n", g(3, f1));  //这种方式也被称为注册,将f1注册给g

    printf("x * f2(x): %d\n", g(3, f2));

    printf("x * f3(x): %d\n", 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 *型形参的函数,这个函数返回一个指向具有5int元素的数组的指针。可以从内向外扒开一会,又可以从外向内扒开一会。

*/

}

 

 

猜你喜欢

转载自www.cnblogs.com/free-1122/p/9783858.html