【C语言复习(十九)】函数与指针

1、函数的类型

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

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

例如:int func(int i,int j);类型为:int(int,int)

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

typedef type name(parameter list)

例如:typedef int INT(int,int)

 2、函数指针

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

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

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

可直接定义函数指针:type (*pointer)(parameter list);

Pointer 为函数指针变量名;

Type 为指向函数的返回值类型;

Parameter list 为指向函数的参数类型列表;

3、函数指针的本质与使用

#include <stdio.h>
 
typedef int FUNC(int);//给函数类型int(int)定义别名
 
int func(int num)
{
    return num*num;
}
 
void fun()
{
    printf("函数fun执行过...");
}
int main()
{
    
    FUNC* p=func;//用定义的别名FUNC定义指向int(int)型函数的指针,函数名代表入口地址
    void(*pf)()=&fun;
    //也可这么定义函数指针,取地址符&作用与函数名得到的也是函数入口地址,这点和数组不同
 
    printf("%d\t%d\n",p(5),(*p)(5));
    pf();
    (*pf)();
    //以上的调用方式本质上是一样的,都能调用函数
    return 0;
}
 

4、回调函数

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

回调机制原理:

调用者不知道具体事件发生时需要调用的具体函数;

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

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

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

本质上,回调函数就是通过指向函数的指针动态的调用类型相同,函数体不同的函数;

示例:

#include <stdio.h>
 
typedef int(*FUNCTION)(int);//定义别名
 
//接收函数指针
int g(int n, FUNCTION 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));//注册函数f1
    printf("x * f2(x): %d\n", g(3, f2));//注册函数f2
    printf("x * f3(x): %d\n", g(3, f3));//注册函数f3
}
 

5、指针的阅读技巧

右左法则:

  • 从最里层的圆括号中未定义的标识符看起;
  • 首先往右看,再往左看;
  • 当遇到圆括号或者方括号时,可以先确定部分类型,然后调转方向继续看;
  • 重复2--3步骤,知道阅读结束;

 

举例:

阅读下列复杂指针:


     int (*p2)(int*, int (*f)(int*));

未定义的标识符为p2,接着往右看,遇到圆括号,调转方向往左看,得到:(*p2),可知这是一指针,然后从原表达式中去掉它,得到:int  (int*, int (*f)(int*)); 接着往右看;

看到括号’(’,看完,可以确定部分类型,得知p2应该指向一个函数,那么这函数是什么类型呢?继续看可知,该函数返回值为int,第一个参数为int*型指针,第二个参数是int(int*)型函数指针。


    int (*p3[5])(int*);

未定义的标识符为p3,往右看,看到方括号,可以确定部分类型:p3[5],得知p3是一个数组,然后删去这一部分,得到:int (*)(int*); 接着看到了圆括号,得到:”(*)”可以确定部分类型,原来p3是一个指针数组,有5个元素,接着去掉这一部分:int (int*); 可知这是一函数类型,返回值为int,参数为int*型指针,即是p3是一个指向int(int*)类型的函数指针数组,有5个元素;

    

    int (*(*p4)[5])(int*);
未定义的标识符为p4,向右看遇到圆括号,方向得到:(*p4),得知p4是一个指针,然后去掉此部分:int (*[5])(int*); 继续往右看,看到方括号,得到:[5]得知p4为数组指针,数组中有5个元素,再去掉此部分:int (*)(int*); 继续往右看,得到:(*)可以确定部分类型,得知p4的数组元素为指针,然后去掉此部分:int (int*);得知这是一个函数类型,因此p4为一个数组指针,这个数组每个元素也为指针,且指向类型为int (int*)的函数


    int (*(*p5)(int*))[5];

为定义的标识符为:p5,向右看到圆括号,调转方向继续看,得到:(*p5),得知p5为一个指针;去掉此部分:int (*(int*))[5]; 接着向右看,看到圆括号,得到:(int*)得知p5为一个函数指针,且参数为一个int*型指针;那么返回值是什么呢?去掉此部分,继续看:

int (*)[5];得到:(*)可知返回值为指针,然后去掉此部分:int[5]这是一个数组类型,即是返回值为int(*)[5]的数组指针;即是:p5是一个函数指针,函数的返回值为int(*)[5]类型的数组指针,参数为int*型指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值