函数指针

@

函数指针

定义

函数指针(也称为子例程指针或过程指针)是指向函数的指针。与引用数据不同, 函数指针指向内存中的可执行代码。解引用函数指针时, 就如同引用函数一样, 可以调用和传递参数。 这样的调用就称之为间接调用, 因为函数是通过变量间接调用的,而不是直接通过固定的标识符或地址调用。

声明

类型说明符 (*函数名) (参数)

比如

int (*p)(int x, int  y);// 该函数指针对应的函数指针类型为 int (*) (int a, int b);
void (*foo)(int);

初始化

  • 方式一:对应的函数名赋值给变量
  • 方式二:函数名前加 & 符号再赋值给变量

其实两种方式是一样的。 就如同数组, 我们可以通过 &变量名 的方式取得数组的地址, 也可以通过直接 变量名 取得地址。

举例

double cm_to_inches(double cm) 
{
    return cm / 2.54;
}
double (*func1)(double) = cm_to_inches;
// 或 double (*func1)(double) = &cm_to_inches;

c 语言中的示例

#include <stdio.h>  /* for printf */
#include <string.h> /* for strchr */

double cm_to_inches(double cm) 
{
    return cm / 2.54;
}

// "strchr" is part of the C string handling (i.e., no need for declaration)
// See https://en.wikipedia.org/wiki/C_string_handling#Functions

int main(void) 
{
    double (*func1)(double) = cm_to_inches;
    char * (*func2)(const char *, int) = strchr;
    printf("%f %s", func1(15.0), func2("Wikipedia", 'p'));
    /* prints "5.905512 pedia" */
    return 0;
}

结果
运行结果与原函数一致
直接调用函数, 肯定是比使用函数指针方便, 容易。而函数指针在作为回调函数时可以让我们的编程变得更加简单。

#include <math.h>
#include <stdio.h>


// Function taking a function pointer as an argument
double compute_sum(double (*funcp)(double), double lo, double hi)
{
    double sum = 0.0;
    // Add values returned by the pointed-to function '*funcp'
    int i;
    for(i = 0;  i <= 100;  i++) 
    {
        // Use the function pointer 'funcp' to invoke the function
        double x = i / 100.0 * (hi - lo) + lo;
        double y = funcp(x);
        sum += y;
    }
    return sum / 101.0;
}

double square(double x) 
{
     return x * x;
}

int main(void) 
{
    double  sum;
    // Use standard library function 'sin()' as the pointed-to function

    sum = compute_sum(sin, 0.0, 1.0);
    printf("sum(sin): %g\n", sum);
    
    // Use standard library function 'cos()' as the pointed-to function
    sum = compute_sum(cos, 0.0, 1.0);
    printf("sum(cos): %g\n", sum);

    // Use user-defined function 'square()' as the pointed-to function

    sum = compute_sum(square, 0.0, 1.0);
    printf("sum(square): %g\n", sum);

    return 0;

}

结果
运行结果
在以上的函数中, 使用函数指针在另一个函数(compute_sum)中调用所传入的函数(如 sin, con, square)。在该过程中, compute_sum函数通过funcp所传入的函数, 实现compute_sum函数达到不同的效果。

与typedef结合

在实际的使用过程中, 为了更易于阅读, 更多的会结合typedef方式进行。

#include <stdio.h>  /* for printf */
#include <string.h> /* for strchr */

typedef double(*Func1)(double);
typedef char* (*Func2)(const char *, int);

double cm_to_inches(double cm) 
{
    return cm / 2.54;
}

int main(void) 
{
    Func1 func1 = cm_to_inches;
    Func2 func2 = strchr;
    printf("%f %s", func1(15.0), func2("Wikipedia", 'p'));
    /* prints "5.905512 pedia" */
    return 0;
}

函数指针数组

其声明如下

类型说明符 (*函数名[数组长度]) (参数) 

举个例子

#include <stdio.h>  /* for printf */

char * fun1(char * p)
{
    printf("%s\n", p);
    return p;
}
char * fun2(char * p)
{
    printf("%s\n", (p+1));
    return p;
}
char * fun3(char * p)
{
    printf("%s\n", (p+2));
    return p;
}
int main() {
    char * (*pf[3])(char * p);
    pf[0] = fun1; 
    pf[1] = &fun2; 
    pf[2] = &fun3;
    pf[0]("fun1");
    pf[1]("fun2");
    pf[2]("fun3");
    
    /**
     * 输出:
     *  fun1
     *  un2
     *  n3
     */
    return 0;
}

结果

结果
或者使用函数指针声明成数组的形式。

#include <stdio.h>  /* for printf */

typedef char * (*Func)(char * p);

char * funa1(char * p)
{
    printf("%s\n", p);
    return p;
}
char * funa2(char * p)
{
    printf("%s\n", (p + 1));
    return p;
}
char * funa3(char * p)
{
    printf("%s\n", (p + 2));
    return p;
}
int main()
{
    Func pf[3];
    pf[0] = funa1;
    pf[1] = funa2;
    pf[2] = funa3;

    pf[0]("Func0");
    pf[1]("Func1");
    pf[2]("Func2");
    return 0;
}

结果如下
运行结果

注意事项

  • 赋给函数指针的函数应该和函数指针所指的函数原型(返回值, 参数一致)是一致的
  • 函数指针没有 ++ 和 -- 操作

转载于:https://www.cnblogs.com/homejim/p/9996453.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值