C++中函数指针详解及代码分享

yizhihongxing

关于“C++中函数指针详解及代码分享”的完整攻略,我为大家总结如下:

1. 什么是函数指针?

函数指针是一个指向函数的指针变量。函数指针可以像普通函数一样被调用,其语法形式为:

返回值类型 (*指针变量名)(参数列表);

其中,指针变量名可以被赋值为相同参数列表和返回类型的函数地址。可以使用函数指针来传递函数作为参数、实现回调函数等。

举个例子,假如我们有一个求和函数:

int add(int x, int y) {
    return x + y;
}

我们就可以定义一个指向该函数的函数指针:

int (*p)(int, int) = add;

这里,(*p)表示声明p为一个指针变量,指向返回类型为int,参数列表为(int, int)的函数,最后将指针变量p赋值为add函数的地址,即可使用p来调用add函数。

2. 两个示例说明函数指针的应用

示例一:函数指针作为参数传递

函数指针可以作为函数参数传递,使用函数指针可以实现更加灵活的代码结构和可复用性。

比如,我们有一个函数,用于将数组按照从小到大的顺序排序:

void sort(int arr[], int len) {
    // 冒泡排序算法实现
}

如果我们现在想对一个字符串数组按照字典序排序,就需要自己编写一个新的排序函数。但如果我们定义一个指向比较函数的指针,则可以传入不同的比较函数来完成不同的排序功能。比如:

int cmp(const char* a, const char* b) {
    return strcmp(a, b) < 0;
}

void sortStr(char* arr[], int len, int (*cmpFunc)(const char*, const char*)) {
    // 根据 cmpFunc 实现排序
}

char* strArr[] = {"hello", "world", "cpp", "function", "pointer"};
int len = sizeof(strArr) / sizeof(char*);
sortStr(strArr, len, cmp);
// 排序后,strArr为{"cpp", "function", "hello", "pointer", "world"}

这里,我们定义了一个cmp函数,用来比较两个字符串的字典序大小。然后,我们定义了一个sortStr函数,用来按照字典序排序一个字符串数组。该函数的第三个参数是一个指向比较函数的指针,可以通过传入不同的比较函数实现不同的排序功能。最后,我们通过传入cmp函数的指针来实现对字符串数组的排序。

示例二:函数指针实现回调函数

在图形用户界面GUI编程中,回调函数是一种常用的技术。它可以使程序在特定的事件发生时,或者用户执行某些操作时,调用指定的处理函数。函数指针可以被用于实现这种技术。

比如,我们在GUI程序中有一块文本编辑的区域,在用户输入时,我们需要实时统计已输入字符的数量。这时,我们可以通过定义回调函数和函数指针的方式来实现。

首先,我们定义一个回调函数,用来统计已输入的字符数:

int countChars(const char* str) {
    return strlen(str);
}

然后,我们在文本编辑器中注册该回调函数:

class TextEditor {
public:
    TextEditor() {
        m_callback = NULL;
        m_str = "";
    }

    void setCallback(int (*callback)(const char*)) {
        m_callback = callback;
    }

    void setInputStr(const std::string& str) {
        m_str = str;
        if (m_callback != NULL) {
            // 调用回调函数,统计字符数
            int num = m_callback(m_str.c_str());
            std::cout << "已输入 " << num << " 个字符\n";
        }
    }

private:
    int (*m_callback)(const char*);
    std::string m_str;
};

这里,我们在TextEditor类中定义了一个函数指针m_callback,用于指向已注册的回调函数(如果用户没有注册回调函数,则m_callback为NULL)。在setInputStr函数中,如果m_callback不为NULL,则调用回调函数来统计输入字符的数量。

现在,我们可以把countChars作为回调函数传入TextEditor中:

TextEditor editor;
editor.setCallback(countChars);

editor.setInputStr("Hello world"); // 输出 "已输入 11 个字符"
editor.setInputStr("C++ function pointer"); // 输出 "已输入 21 个字符"

这里,我们通过setCallback函数将countChars函数指针传入TextEditor中,并调用setInputStr函数来模拟用户不断输入字符串的场景。每次输入后,程序会自动调用回调函数来统计已输入字符的数量。

3. 代码分享

最后,我给大家分享一个简洁的函数指针示例代码。该代码定义了一个名为sum的函数,用于求任意两个数的和。其中,函数指针可以用于表示不同的数处理方法。

#include <iostream>

int normalFunc(int a, int b) {
    return a + b;
}

int times2(int a, int b) {
    return (a << 1) + (b << 1);
}

int times3(int a, int b) {
    return (a * 3) + (b * 3);
}

int sum(int a, int b, int (*f)(int, int)) {
    return f(a, b);
}

int main() {
    int a = 2, b = 3;
    std::cout << "sum = " << sum(a, b, normalFunc) << std::endl; // 输出 "sum = 5"
    std::cout << "sum * 2 = " << sum(a, b, times2) << std::endl; // 输出 "sum * 2 = 10"
    std::cout << "sum * 3 = " << sum(a, b, times3) << std::endl; // 输出 "sum * 3 = 15"
    return 0;
}

这里,我们定义了三个不同的数处理函数:normalFunc、times2和times3。它们分别表示两个数相加、两个数乘以2和两个数乘以3的结果。然后,我们在sum函数中定义了一个函数指针f,用于表示不同的数处理方法。最后,在main函数中,我们分别通过调用sum函数来测试三种不同的处理方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++中函数指针详解及代码分享 - Python技术站

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

相关文章

  • VSCode launch.json配置详细教程

    首先,我们需要了解什么是VSCode的launch.json文件。launch.json是配置VSCode调试器的文件,在这个文件中,我们可以设置如何运行我们的代码、哪些文件需要调试、以及如何传递命令行参数等等。 接下来,让我们通过以下步骤创建一个新的launch.json文件: 在VSCode中打开你的项目文件夹。 打开调试器工具栏。(快捷键F5) 在工具…

    C 2023年5月23日
    00
  • C++深复制和浅复制讲解

    C++中的复制操作包含深复制和浅复制两种方式。简单来说,浅复制只复制指针而不复制指针指向的内存空间,而深复制会复制指针和指针指向的内存空间。 一般情况下,我们需要使用深复制,以避免浅复制造成指针指向错误的情况。 深复制的实现方式 在C++中,可以通过使用拷贝构造函数和赋值操作符实现深复制。 拷贝构造函数 拷贝构造函数是一种特殊的构造函数,用于在创建对象时,用…

    C 2023年5月23日
    00
  • PyPy 如何让Python代码运行得和C一样快

    PyPy(Python运行时编译器)是一个替代CPython(官方Python解释器)的选择。它通过JIT(即时编译)技术不断优化代码,使得Python执行速度与C语言一样快。攻略如下: 步骤1:安装PyPy 在PyPy的官方网站上下载与您的操作系统相关的二进制文件。然后解压缩文件,将可执行文件添加到您的系统环境变量。 步骤2:运行PyPy PyPy提供了一…

    C 2023年5月23日
    00
  • C++ 智能指针深入解析

    C++ 智能指针深入解析 什么是智能指针? 在C++中,一个指针指向某个变量,但是由于指针是”裸”的,需要程序员显式地管理其生命周期。为了解决这个问题,C++11引入了智能指针。智能指针的用法和裸指针类似,但是会自动管理指针所指对象的生命周期。 智能指针的分类 C++中常用的智能指针有三种,它们分别是: unique_ptr:独占所有权的智能指针 share…

    C 2023年5月22日
    00
  • C++学习进阶篇之类大小计算和this指针

    C++学习进阶篇之类大小计算和this指针 类大小计算 在C++中,类的大小计算是非常重要的。一个类的大小包括它所占用的存储空间以及它所包含的成员变量所占用的存储空间。在计算类的大小时,通过以下几个方面来确定: 子对象的大小 虚拟函数表指针的大小 数据成员的大小 子对象的大小 类可能会继承其他类,所以需要考虑子对象的大小。子对象的大小实际上是在编译时计算的,…

    C 2023年5月30日
    00
  • C程序 检查闰年

    C程序 检查闰年使用攻略 简介 本文将介绍如何使用C程序来检查一个年份是否为闰年。闰年是指能被4整除的年份,但是不能被100整除的年份,或者能够被400整除的年份。文章将包括程序示例和思路讲解。 示例代码 下面是一个简单的C程序,它使用函数来检查一个给定年份是否为闰年。该函数返回一个整数值,如果该年份是闰年则返回1,否则返回0。 #include <s…

    C 2023年5月9日
    00
  • C++中Lambda表达式的语法与实例

    下面是C++中Lambda表达式的语法与实例的详细讲解。 1. Lambda表达式的语法 Lambda 表达式的一般形式如下: [capture list] (parameter list) -> return type { // 函数体 } capture list: 捕获列表,表示可以捕获外部变量,以使用这些变量在 Lambda 表达式中。 par…

    C 2023年5月23日
    00
  • C++中的vector中erase用法实例代码

    C++中的vector中erase用法实例代码 简介 在C++中,vector是一种非常常用的容器,它可以动态地管理内存,能够随时加入或者删除元素。vector的erase方法是其中非常常用的函数之一,通过该函数我们可以删除vector中的元素。 使用方法 vector中的erase函数有多种使用方法,其中比较常用的有两种,分别是通过迭代器和通过下标。下面将…

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