函数指针的应用

一、函数指针实现多态

  • 多态就是同一个执行但是实际结果不一样
  • C语言虽然没有多态,但是可以用函数指针指向不同的函数来实现同一个调用执行不同的结果

1.1 测试代码

#include <stdio.h>

//定义一个pFunc类型,这个函数指针类型指向一种特定参数列表和返回值得函数
typedef int (*pFunc)(int, int);

int add(int a, int b);
int sub(int a, int b);

int multiply(int a, int b);
int divide(int a, int b);

int main(void)
{
    pFunc p1 = NULL;
    int a, b, result = 0;
    char c;
    printf("请输入两个整数:\n");
    scanf("%d%d", &a, &b);
    getchar();//清除缓存区的\n
    printf("请输入运算符: + | - | * | / \n");
    scanf("%c", &c);
    
    /*用函数指针指向不同的函数*/
    p1 = c == '+' ? add : (c == '-' ? sub : (c == '*' ? multiply : divide));
    
    result = p1(a, b);
    printf("%d %c %d = %d\n",a, c, b, result);
    return 0;
}

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

int sub(int a, int b)
{
    return a - b;
}

int multiply(int a, int b)
{
    return a * b;
}

int divide(int a, int b)
{
    return a / b;
}

1.2 测试结果

多态

  • 我们可以发现,通过同一个执行p1(int, int),其返回的结果是可以不同的,这也就实现了多态
  • 测试代码中加入getchar();是为了清除缓冲区的'\n'linux为了提升效率,默认将输入的内容放在缓存区等一行输入完了再一次性把一行全部输出出来,判断一行有没有完的依据就是'\n'

二、结构体内嵌函数指针实现模块化编程

2.1 完成架构设计

1.1所述的简单计算器测试代码,我们可以将其分为

  • 上层:架构层:framework.c——应用程序框架的实现
  • 下层:原理层:calculator.c——业务原理的具体实现
  • 头文件:calculator.h——实现架构层与原理层之间的信息传递

实际工作时calculator.c是直接完成工作的,但是其中的关键部分是调用framework.c中的函数来完成的

2.2 头文件calculator.h参考代码

头文件用来实现不同层次之间的交互,需要注意:

  • 普通变量不要在头文件中定义
  • 枚举或者结构体要定义在头文件中
#ifndef _CALCULATOR_H_
#define _CALCULATOR_H_

/*定义函数指针*/
typedef int (*pFunc)(int, int);

/*定义接口*/
struct calculator_t
{
    int a;
    int b;
    pFunc p_cal;
};

/*函数原型声明*/
int calculator(const struct calculator_t *p);
int add(int a, int b);
int sub(int a, int b);
int multiply(int a, int b);
int divide(int a, int b);

#endif

2.3 架构层:framework.c 参考代码

架构层只需实现业务逻辑,为原理层提供一个函数接口(不用干活)

#include "calculator.h"
//上层接口
int calculator(const struct calculator_t *p)
{
    return p -> p_cal(p->a, p->b);
};

2.4 原理层:calculator.c 参考代码

注重实际实现,需要使用架构层的接口与头文件,填充上层的空白

  • 定义结构体变量
  • 填充结构体变量
  • 调用接口函数,传入参数
#include "calculator.h"
#include <stdio.h>

int main(void)
{
    /*定义结构体变量*/
    struct calculator_t my_cal;

    pFunc p1;
    int a, b, result = 0;
    char c;
    printf("请输入两个整数:\n");
    scanf("%d%d", &a, &b);
    printf("请输入运算符: + | - | * | / \n");
    getchar();//清除缓存区的\n
    scanf("%c", &c);
    p1 = c == '+' ? add : (c == '-' ? sub : (c == '*' ? multiply : divide));

   /*填充结构体变量*/
    my_cal.a = a;
    my_cal.b = b;
    my_cal.p_cal = p1;  

   /*调用接口函数,传入参数*/
    result = calculator(&my_cal);

    printf("%d %c %d = %d\n",a, c, b, result);

    return 0;
}

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

int sub(int a, int b)
{
    return a - b;
}

int multiply(int a, int b)
{
    return a * b;
}

int divide(int a, int b)
{
    return a / b;
}

2.5 测试结果

涉及到多个.c文件的编译:
$ gcc framework.c calculator.c -o XXX.exe

模块化编程.png

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值