第1章 基础知识
1.1 函数名是地址
/*抽象的接口函数(函数指针)*/
int (*pFunc)(int a);
/*定义一个函数*/
int func(int a)
{
return a + 1;
}
/*将接口和函数绑定(复制)*/
pFunc = func;
/*函数调用*/
int result = pFunc(12);
1.2 数组名是地址
int arr[] = {12, 1, 56, 5689};
int *pArr = arr;
1.3 不推理的写法
不推荐理由:不符合人类观感。
// 1
int (*pFunc)(int a) = func;
// 2
int (*pFunc[])(int a) = {func1, func2, func3};
// 3
int *pArr = arr;
// 4
void task(int (*pFunc)(int a))
{
}
符合人类感受的写法;
// 1
typedef int (*pFunc)(int a);
pFunc pfn;
pfn = func;
// 2
pFunc taskFuncArr[] = {func1, func2, func3};
// 3
int *pArr = &arr[0];
// 4
void task(pFunc pfn)
{
}
通过typedef关键字完成符合人类观感的写法。
第2章 注册机制
注册机制的核心思想:
1. 抽象(采样函数指针抽象出函数接口)
2. 数组(采样的数据结构,类似Excel记录数据)
不推荐使用malloc函数,而推荐数组。不推荐理由,规避内存管理。
2.1 使用函数来动态注册
假定有一个业务场景,学生的信息管理系统。
入职第一天需要应届生做自我介绍,每个人的自我介绍(展示特长)的方式不一致,需要对自我介绍做高度抽象。
头文件(student.h)
#ifndef STUDENT_H
#define STUDENT_H
// 定义自我介绍函数的类型
typedef void (*SelfIntro)(void);
// 学生结构体
typedef struct {
int num; // 学号
float score; // 成绩
SelfIntro pfnSelf; // 自我介绍函数指针
}TStudent_t;
// 声明全局学生数组
extern TStudent_t students[];
// 使用函数动态向数组中注册学生信息
int registerStudent(int index, int num, float score, SelfIntro introFunc);
void printAllSelfIntros(int count);
#endif // STUDENT_H
源文件(student.c)
#include "student.h"
#include <stdio.h>
// 最大学生数量
#define MAX_STUDENTS 3
// 全局学生数组定义
TStudent_t students[MAX_STUDENTS] = {0};
// 注册学生到数组中
int registerStudent(int index, int num, float score, SelfIntro introFunc) {
if (index >= MAX_STUDENTS || index < 0) {
printf("索引越界!\n");
return -1;
}
students[index].num = num;
students[index].score = score;
students[index].pfnSelf = introFunc;
return 0;
}
// 打印所有学生的自我介绍
void printAllSelfIntros(int count) {
for (int i = 0; i < count; ++i) {
printf("ID: %d, score: %.2f\n", students[i].num, students[i].score);
if (students[i].pfnSelf != NULL) {
students[i].pfnSelf();
} else {
printf("no selfIntroduction。\n");
}
}
}
main.c
#include "student.h"
#include <cstdio>
// 示例自我介绍函数
void student1() {
printf("student 1 SelfIntro\n");
}
void student2() {
printf("student 2 SelfIntro\n");
}
void student3() {
printf("student 3 SelfIntro\n");
}
int main() {
// 注册学生
registerStudent(0, 1001, 85.5, student1);
registerStudent(1, 1002, 90.0, student2);
registerStudent(2, 1003, 78.0, student3);
// 打印所有学生的自我介绍
printAllSelfIntros(3);
return 0;
}
2.2 使用数组来静态注册
头文件(student.h)
#ifndef STUDENT_H
#define STUDENT_H
// 定义自我介绍函数的类型
typedef void (*SelfIntro)();
// 学生结构体
typedef struct {
int num; // 学号
float score; // 成绩
SelfIntro pfnSelf; // 自我介绍函数指针
}TStudent_t;
// 声明全局学生数组和数量
extern TStudent_t students[];
extern const int studentCount;
// 打印所有学生的自我介绍
void printAllSelfIntros();
#endif // STUDENT_H
源文件(student.c)
// student.c
#include "student.h"
#include <stdio.h>
// 示例自我介绍函数
static void student1() {
printf("student 1 SelfIntro.\n");
}
static void student2() {
printf("student 2 SelfIntro.\n");
}
static void student3() {
printf("student 3 SelfIntro. \n");
}
// 静态初始化的学生数组
TStudent_t students[] = {
{1001, 85.5f, student1},
{1002, 90.0f, student2},
{1003, 78.0f, student3}
};
// 学生数量
const int studentCount = sizeof(students) / sizeof(students[0]);
// 打印所有学生的自我介绍
void printAllSelfIntros() {
for (int i = 0; i < studentCount; ++i) {
printf("ID: %d, score: %.2f\n", students[i].num, students[i].score);
if (students[i].pfnSelf != NULL) {
students[i].pfnSelf();
} else {
printf("no selfIntroduction。\n");
}
}
}
main.c
// main.c
#include "student.h"
int main() {
// 直接打印静态注册的学生信息
printAllSelfIntros();
return 0;
}