C语言 函数指针

C语言 函数指针使用攻略

函数指针是C语言中一个非常有用的特性,它允许我们将函数的地址作为参数传递给另一个函数,或者作为另一个函数的返回值,从而提高函数的灵活性和可重用性。下面将详细介绍如何使用函数指针。

函数指针的声明

函数指针的声明与变量的声明类似,只不过要在函数名前加上“*”,例如:

int (*p)(int, int);

表示“p”是一个指向返回类型为int,参数类型为int和int的函数指针。注意,函数指针的类型要与被指向函数的类型严格匹配。

函数指针的定义与赋值

函数指针的定义与变量的定义类似,可以在声明时同时定义,也可以单独定义。例如:

int (*p)(int, int) = NULL;
p = func;

其中,“func”是一个函数名,表示函数的地址。函数指针可以通过“&”符号取得函数的地址,例如:

p = &func;

函数指针也可以作为参数传递给函数,例如:

void print(int (*p)(int, int), int x, int y)
{
    printf("%d\n", p(x, y));
}

这个函数接收一个函数指针“p”作为参数,并且调用“p”函数,传递两个整数参数“x”和“y”。当“p”被调用时,实际执行的是“p”所指向的函数。

函数指针还可以作为函数的返回值,例如:

int (*getFunc())(int, int)
{
    return func;
}

这个函数返回一个函数指针,指向一个返回类型为int,参数类型为int和int的函数。

示例1:排序函数

函数指针特别适合用于实现通用的排序函数。例如,下面是一个采用函数指针实现的快速排序函数:

void quickSort(int *arr, int left, int right, int (*cmp)(int, int))
{
    if (left >= right) {
        return;
    }
    int pivot = arr[(left + right) / 2];
    int i = left, j = right;
    while (i <= j) {
        while (cmp(arr[i], pivot)) {
            i++;
        }
        while (cmp(pivot, arr[j])) {
            j--;
        }
        if (i <= j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
    }
    quickSort(arr, left, j, cmp);
    quickSort(arr, i, right, cmp);
}

这个函数接收一个整数数组“arr”,数组的左边界“left”和右边界“right”,以及一个函数指针“cmp”。在排序过程中,通过“cmp”指向的函数来比较两个整数的大小,从而实现升序排列或降序排列。

下面是一个比较函数的示例,用于按照升序排列:

int cmpAsc(int a, int b)
{
    return a < b;
}

我们可以将这个比较函数传递给快速排序函数,并对一个整数数组进行排序:

int main()
{
    int arr[] = {6, 2, 3, 5, 4, 1};
    int size = sizeof(arr) / sizeof(arr[0]);
    quickSort(arr, 0, size - 1, cmpAsc);
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

输出结果为:

1 2 3 4 5 6

示例2:回调函数

函数指针还可以用于回调函数的实现。回调函数是指在一个函数中调用另一个函数,并以函数指针的形式将回调函数传递给被调用的函数。回调函数常用于事件处理、状态监测等场合。

例如,下面是一个模拟登录的函数,用于验证用户名和密码是否正确:

int login(char *username, char *password)
{
    if (strcmp(username, "admin") == 0 && strcmp(password, "admin123") == 0) {
        return 1;
    } else {
        return 0;
    }
}

这个函数接收两个字符串参数“username”和“password”,如果用户名和密码正确,则返回1,否则返回0。

我们可以写一个登录界面,并使用回调函数来处理登录成功和失败事件:

void onLoginSuccess()
{
    printf("Login success!\n");
}

void onLoginFailure()
{
    printf("Login failure!\n");
}

int main()
{
    char username[64], password[64];
    printf("Username: ");
    scanf("%s", username);
    printf("Password: ");
    scanf("%s", password);
    if (login(username, password)) {
        onLoginSuccess();
    } else {
        onLoginFailure();
    }
    return 0;
}

在这个程序中,如果登录成功,则调用“onLoginSuccess”函数,否则调用“onLoginFailure”函数。我们可以像这样编写任意类型的回调函数,并将其传递给各种各样的函数,用于处理不同的业务逻辑。

总结

函数指针是C语言中一个非常有用的特性,可以提高函数的灵活性和可重用性。在实际编程中,我们可以利用函数指针来实现通用的排序、查找、回调等功能,提高程序的效率和健壮性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言 函数指针 - Python技术站

(0)
上一篇 2023年5月9日
下一篇 2023年5月9日

相关文章

  • DEVC++实现推箱子小游戏

    DEVC++实现推箱子小游戏攻略 推箱子小游戏是一款非常经典的益智游戏,玩家需要在限定步数内将箱子推到指定位置才能过关。本文将介绍如何使用DEVC++实现推箱子小游戏。 第一步:框架搭建 首先,我们需要创建一个控制台应用程序项目。 打开DEVC++软件,选择“文件”-“新建”-“项目”,进入“新建项目”界面。 在“项目类型”中选择“控制台应用程序”,在“基于…

    C 2023年5月24日
    00
  • C语言实现单链表

    C语言实现单链表的完整使用攻略 什么是单链表 单链表是一种常见的数据结构,它的每个节点包含两部分内容,一个是存放数据的数据域,另一个是指向下一个节点的指针域。单链表的特点是插入和删除操作非常快,但查询操作相对较慢。 单链表的实现步骤 实现一个单链表需要以下步骤: 定义节点结构体:定义一个结构体,包含数据域和指针域两个成员。 创建节点:通过malloc函数动态…

    C 2023年5月9日
    00
  • win10系统升级提示错误代码0x80070006-0x2000c该怎么解决

    win10系统升级提示错误代码0x80070006-0x2000c的解决方法 出现win10系统升级提示错误代码0x80070006-0x2000c的原因很多,包括错误的系统配置,损坏的文件或注册表项,软件冲突等等。下面是一些常用的解决方法: 方法一:运行Windows更新故障排除工具 Windows更新故障排除工具是解决Win10升级问题的有力工具。以下是…

    C 2023年5月23日
    00
  • Flash Actionscript 优化指南

    Flash Actionscript 优化指南 为什么需要优化 在开发复杂的Flash应用程序时,如不进行优化,可能出现以下问题: 程序速度变慢,用户体验变差。 耗费更多的CPU周期和内存,使程序更容易崩溃。 代码杂乱无章,难以维护和扩展。 因此,优化是每个Flash开发人员必须掌握的技能。 优化方法 以下是几种常见的优化方法: 1. 尽量避免使用深度嵌套显…

    C 2023年5月22日
    00
  • 深入N皇后问题的两个最高效算法的详解

    让我来详细讲解一下“深入N皇后问题的两个最高效算法的详解”。 算法一:位运算 算法思路 基于位运算的 N 皇后问题算法,是一种高效的算法。其核心思路在于将每行、每列、每条对角线(包括左上角至右下角、右上角至左下角)都用一个二进制数来表示,通过位运算的方式来判断该位置是否可以放皇后。 其中,用两个 int 类型的变量 col 和 ld 来表示列和左对角线(左上…

    C 2023年5月22日
    00
  • Linux网络编程:socket实现client/server通信

    一、问题引入 阅读UNIX网络编程 卷1:套接字联网API 第3版的前4个章节,觉得有必要对书籍上的源码案例进行复现,并推敲TCP的C/S通信过程。 二、解决过程 2-1 server #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #in…

    C 2023年5月11日
    00
  • MySQL数据库恢复(使用mysqlbinlog命令)

    MySQL数据库恢复是重要的运维工作之一。使用mysqlbinlog命令恢复MySQL数据库是一种常见方法。以下是使用mysqlbinlog命令恢复MySQL数据库的完整攻略: 1.备份原始的MySQL数据 在恢复MySQL数据库之前,必须确保已经备份了原始的MySQL数据,以便在恢复失败时能够恢复到原始状态。一般情况下,可以使用mysqldump命令进行备…

    C 2023年5月23日
    00
  • socket多人聊天程序C语言版(一)

    下面是“socket多人聊天程序C语言版(一)”的完整攻略。 一、前置知识 在学习本文前,需要掌握以下C语言知识:- socket编程基础- 线程基础- 指针基础 二、程序结构 本程序主要分为四个模块:客户端、服务端、公共头文件和Makefile。 1. 公共头文件 common.h:包含了各种结构体和宏定义,以及客户端和服务端公共使用的函数的声明。 2. …

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部