• C语言函数指针的用法


    函数指针是一种在C、C++、D语言、其他类 C 语言和Fortran 2003中的指针。函数指针可以像一般函数一样,用于调用函数、传递参数。在如 C 这样的语言中,通过提供一个简单的选取、执行函数的方法,函数指针可以简化代码。

    函数指针只能指向具有特定特征的函数。因而所有被同一指针运用的函数必须具有相同的参数和返回类型。

    本文地址:http://www.cnblogs.com/archimedes/p/3669872.html,转载请注明源地址。

    下面的代码说明了一种初始化函数指针的方法:

    int f(int);
    int (*fp)(int) = &f;
    
    //使用三种方式调用函数
    int ans;
    ans = f(25);
    ans = (*pf)(25);
    ans = pf(25);

    以下为函数指针在C中的简单运用:

    #include <stdio.h>
    
    int max(int x, int y)
    {
        return x > y ? x : y;
    }
     
    int main(void)
    {
        /* p 是函数指针 */
        int (* p)(int, int) = & max; // &可以省略
        int a, b, c, d;
     
        printf("please input 3 numbers:");
        scanf("%d %d %d", & a, & b, & c);
     
        /* 与直接调用函数等价,d = max(max(a, b), c) */
        d = (* p)(( *p)(a, b), c); 
     
        printf("the maxumum number is: %d
    ", d);
        return 0;
    }

    下面介绍函数指针最常见的两个用途:作为参数传递给另一个函数(回调函数)、转换表

    1、回调函数:

    下面有一个简单的函数,用来在单链表中查找一个给定的值

    Node* search_list(Node* node, int const value)
    {
        while(node != NULL) {
            if(node->value == value)
                break;
            node = node->next;
        }
        return node;
    }

    一种更加通用的方法就是使该函数能用任何类型值的链表,必须修改函数,使它与类型无关。解决的方案就是使用函数指针。

    #include <stdio.h>
    #include "node.h"
    
    Node *search_list( Node *node, void const *value,
        int (*compare)( void const *, void const * ) )
    {
        while( node != NULL ){
            if( compare( &node->value, value ) == 0 )
                break;
            node = node->next;
        }
        return node;
    }

    在特定的链表中进行比较的时候,用户需要编写适当的比较函数,并把指向该函数的指针和指向需要查找的值的指针传递给查找函数,下面是一个整型链表中查找的比较函数:

    int compare_ints(void const *a, void const *b)
    {
        if( *(int *)a == *(int *)b)
            return 0;
        else
            return 1;
    }
    
    //这个函数将像下面这样调用
    desired_node = search_list(root, &desired_value, compare_ints);

    如果你希望在一个字符串链表中进行查找,下面的代码可以完成任务:

    #include<string.h>
    ...
    desired_node = search_list(root, "desired_value", strcmp);

    再看一个完整的例子:

    #include<stdio.h>
    struct object
    {
        int data;
    };
     
    int object_compare(struct object * a,struct object * z)
    {
        return a->data < z->data ? 1 : 0;
    }
     
    struct object *maximum(struct object * begin,struct object * end,int (* compare)(struct object *, struct object *))
    {
        struct object * result = begin;
        while(begin != end)
        {
            if(compare(result, begin))
            {
                result = begin;
            }
            ++ begin;
        }
        return result;
    }
     
    int main(void)
    {
        struct object data[8] = {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}};
        struct object * max;
        max = maximum(data + 0, data + 8, & object_compare);
        printf("max: %d
    ", (*max).data);
        return 0;
    }

    2、转移表

     下面的程序是一个简化的根据运算符转到相应运算的例子:

    #include<stdio.h>
    
    double _add(double, double);
    double _sub(double, double);
    double _mul(double, double);
    double _div(double, double);
    
    double _add(double a, double b)
    {
        return a + b;
    }
    
    double _sub(double a, double b)
    {
        return a - b;
    }
    
    double _mul(double a, double b)
    {
        return a * b;
    }
    
    double _div(double a, double b)
    {
        return a / b;
    }
    
    int main(void)
    {
        int n;
        enum Operation{ADD, SUB, MUL, DIV}op;
        double a, b, ans;
        a = 0.232332;
        b = 0.234398;
        printf("请输入一个整数(0-3): ");
        scanf("%d", &n);
        op = (enum Operation)n;
        switch(op) {
        case ADD:
            ans = _add(a, b);
            break;
        case SUB:
            ans = _sub(a, b);
            break;
        case MUL:
            ans = _mul(a, b);
            break;
        case DIV:
            ans = _div(a, b);
            break;
        default:
            break;
        }
        printf("%lf
    ", ans);
        return 0;
    }

    使用可以使用转换表来实现相同的任务,转换表就是一个函数指针数组,代码如下:

    #include<stdio.h>
    
    double _add(double, double);
    double _sub(double, double);
    double _mul(double, double);
    double _div(double, double);
    
    double _add(double a, double b)
    {
        return a + b;
    }
    
    double _sub(double a, double b)
    {
        return a - b;
    }
    
    double _mul(double a, double b)
    {
        return a * b;
    }
    
    double _div(double a, double b)
    {
        return a / b;
    }
    
    int main(void)
    {
        int n;
    double a, b, ans; a = 0.232332; b = 0.234398; printf("请输入一个整数(0-3): "); scanf("%d", &n); double (*oper_func[])(double, double) = { _add, _sub, _mul, _div }; ans = oper_func[n](a, b); printf("%lf ", ans); return 0; }

     

  • 相关阅读:
    ZOJ 3018
    poj2464
    Gauss
    【C】关于内存地址
    【C】typedef与define的区别
    C位移操作
    操作系统使用批处理文件更改网络配置
    【Linux】查看某个进程的线程数量(转)
    数据结构快速排序
    C++Explanation of ++val++ and ++*p++ in C
  • 原文地址:https://www.cnblogs.com/wuyudong/p/3669872.html
Copyright © 2020-2023  润新知