函数与指针分析

来源:互联网 发布:口才社交培训机构知乎 编辑:程序博客网 时间:2024/05/10 18:29

函数类型

C语言中的函数有自己特定的类型

函数类型由返回值参数类型参数个数共同决定

参数类型和参数个数隐含了另一个条件:参数顺序

例:int  add(float i, char j) 的类型为int(int, int),其返回值类型是int,有两个参数,第一个参数float,第二个参数char

        int ff(double e, int i);      //ff函数类型为int(double, int)

        int ff(int i, double e);      //gg函数类型为int(int, double)

        因为函数参数顺序不同,所以这两个函数类型不同

C语言中通过typedef为函数类型重命名

typedef  type name(parameter list)

例:    typedef  int f(int, int);  //定义了一个函数类型f,指的是int(int, int)这类型的函数

    typedef void p(int);     //定义了一个函数类型p,指的是void(int)这类型的函数


函数指针

函数指针用于指向一个函数

函数名是执行函数体的入口地址

可通过函数类型定义函数指针:FuncType*pointer;

也可以直接定义:type (*pointer)(parameter list);

.pointer为函数指针变量名

.type为指向函数的返回值类型

.parameter list为指向函数的类型参数列表

例1:

#include <stdio.h>typedef int(FUNC)(int);   //把一个int(int)函数类型重定义为FUNCint test(int i)      //test函数类型也为int(int){    return i * i;}void f()     //f函数类型为void(){    printf("Call f()...\n");}int main(){    FUNC* pt = test;   //test函数类型与重定义的FUNC一致,函数名test就是test函数的入口地址,pt是FUNC类型的函数指针,该指针指向test函数        void(*pf)() = &f;  //偷懒的方式定义了一个函数指针pf,指向的函数类型为void(),因此可以把f函数的地址赋给pf,使pf指向f函数        pf();     //新式方法函数调用    (*pf)();  //老式方法函数调用        printf("Function pointer call: %d\n", pt(2));  //pt(2)等价于直接调用test(2)}
注:对函数名取地址的意义和函数名本身的意义相同,即f和&f意义相同,test和&test意义相同,这一点函数名和数组名不同,主要是历史原因导致,老的编译器按&f的方式,因为这样写起来麻烦,故新的编译器按照直接f的方式,为了兼容老的规则,所以两种方式都支持

回调函数

回调函数是利用函数指针实现的一种调用机制

回调机制原理

.调用者不知道具体事情发生的时候需要调用的具体函数

.被调函数不知道何时被调用,只知道被调用后需要完成的任务

.当具体事情发生时,调用者通过函数指针调用具体函数

回调机制将调用者和被调函数分开,两者互不依赖

例2:

#include <stdio.h>typedef int(*FUNCTION)(int);  //FUNCTION是指针类型 int g(int n, FUNCTION f)   //f是一个指向int(int)类型的函数指针,g就是调用者,f就是被调函数{    int i = 0;    int ret = 0;      for(i=1; i<=n; i++)    {        ret += i*f(i);    }        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));  //g(3, f1)这么写叫注册,把f1作为参数注册给g,g就可以知道f1具体是什么,然后g就可以工作了    printf("x * f2(x): %d\n", g(3, f2));    printf("x * f3(x): %d\n", g(3, f3));  //当发生这个事件时,调用者g去调用f3函数}


指针阅读技巧解析

右左法则

1.从最里层的括号中未定义的标示符看起

2.首先往右看,再往左看

3.当遇到圆括号或者方括号时可以确定部分类型,并调转方向

4.重复2,3步骤,知道阅读结束
例3:

    int (*p2)(int*, int (*f)(int*));
    
    int (*p3[5])(int*);
    
    int (*(*p4)[5])(int*);
    
    int (*(*p5)(int*))[5];

    太麻烦,有空再写


原创粉丝点击