C/C++注册机制

发布于:2025-07-06 ⋅ 阅读:(20) ⋅ 点赞:(0)

第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;
}