一、函数指针实现多态
- 多态就是同一个执行但是实际结果不一样
- 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