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\n", 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\n", (*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\n", 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\n", ans); return 0; }
目录
相关文章
|
3月前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
68 0
|
1月前
|
IDE 编译器 开发工具
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
在本文中,我们系统地讲解了常见的 `#pragma` 指令,包括其基本用法、编译器支持情况、示例代码以及与传统方法的对比。`#pragma` 指令是一个强大的工具,可以帮助开发者精细控制编译器的行为,优化代码性能,避免错误,并确保跨平台兼容性。然而,使用这些指令时需要特别注意编译器的支持情况,因为并非所有的 `#pragma` 指令都能在所有编译器中得到支持。
121 41
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
|
1月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
106 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
1月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
90 9
|
1月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
53 7
|
2月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
222 13
|
2月前
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
79 11
|
2月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
2月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
180 3
|
2月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。

热门文章

最新文章