28. 函数与指针分析

函数类型

C语言中的函数有自己特定的类型
函数的类型由 返回值、参数类型参数个数(包括出现顺序)共同决定
例:int add(int i, intj)的类型为int(int, int)
C语言中 通过typedef为函数类型 重命名
typedef type name(parameter list)
例:
typedef int f(int, int);
typedef void p(int);

函数指针

函数指针用于 指向一个函数
函数名是执行函数体的入口地址
可通过函数类型定义函数指针: 
    typedef type FuncType(parameter list)
    FuncType* pointer;
也可以直接定义: type (*pointer)(parameter list);
. pointer为函数指针变量名
. type为指向函数的返回值类型
. parameter list为指向函数的参数类型列表
例:
#include <stdio.h>
typedef int(FUNC)(int);//定义一个函数类型FUNC
int test(int i)//test函数是FUNC类型的
{
    return i * i;
}
void f()
{
    printf("Call f()...\n");
}
int main()
{
    FUNC* pt = test;//用函数类型FUNC定义了一个指针pt指向函数test
   //函数名就代表了一个地址,把函数名直接赋值给指针;用&作用于函数名和不用没有任何区别
    void(*pf)() = &f;//用偷懒的方式定义了一个函数指针pf,指向函数f;
   
    pf();//pf保存了一个函数地址,且这个函数没有参数,即等价于f()
    (*pf)();//老方法,功能与 pf();一致,通过*打开防盗门,在函数指针pf得到函数f的地址
   
    printf("Function pointer call: %d\n", pt(2));
}
result:
Call f()...
Call f()...
Function pointer call: 4

回调函数

回调函数是利用函数指针实现的一种调用机制
回调机制原理
.   调用者(遇到事情,但不会处理事情) 不知道具体事件发生的时候需要调用的具体函数
.   被调函数(会处理事情,但不会遇到事情) 不知道何时被调用,只知道被调用后需要完成的任务
.   当具体事件发生时,调用者通过函数指针调用具体函数

回调机制要将调用者和被调函数分开,两者互不依赖(有利于模块化编程)

回调函数的使用示例

#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);
    }
   
    return ret;
}
int f1(int x)//锦囊1
{
    return x + 1;
}
int f2(int x)//锦囊2
{
    return 2*x - 1;
}
int f3(int x)//锦囊3
{
    return -x;
}
int main()
{
    printf("x * f1(x): %d\n", g(3, f1));//把f1作为参数注册给g,g就可以具体知道f是什么,就可以工作了
    printf("x * f2(x): %d\n", g(3, f2));
    printf("x * f3(x): %d\n", g(3, f3));
}
result:
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*,类型为int
    //,往左看,类型是int,
    int (*p3[5])(int*);
    //p3未定义,往右看,遇到[,确定p3是一个数组,有5个元素,即p3[5]
    //拿出来已经确定的,变成int (*)(int*);右左法则:继续往左看是),往右看是(,可以确定p3的这五个元素是指针
    //拿出来已经确定的,变成int (int*);往右看,遇到(,p3是函数指针
    //p3是一个包含五个元素的数组,每个元素都包含一个指针,函数指针指向的函数类型是int (int*)
    int (*(*p4)[5])(int*);
    //p4是一个数组指针,指向一个数组,数组有五个元素,
    //每一个元素还是一个指针,每一个指针指向一个函数,函数类型是int (int*)
    int (*(*p5)(int*))[5];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值