C语言_代码分层_结构体嵌套函数指针实现代码分层

这篇笔记记录代码的分层,最后用结构体嵌套函数指针来实现层次化代码。

代码的分层:

作为一名驱动工程师,应该了解代码的层级架构,下面是应用代码,OS和驱动程序的整体关系:
在这里插入图片描述
当代码复杂后,必须要对代码进行一个分层,只有这样代码才会更合理。同时分层也有助于分工合作,不同层的人写不同层的代码。
层与层之间要通过函数来传递信息,当要传递的信息很多时候,就要用结构体来封装要传递的参数,函数中只需传递结构体指针即可。下面用一个例子来说明代码的层次化结构。
在这里插入图片描述
代码调用结果显示如下:
在这里插入图片描述
代码一共7个文件;

main.c

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include "public.h"
#include "stu.h"
#include "tea.h"

#define STUNUM 2
#define TEANUM 2

Stu stu[STUNUM] = { {"张三",10000,90.1},{ "李四",10001,95.5 } };
Tea tea[TEANUM] = { { "老师1",100,1 },{ "老师2",101,2 } };

int main()
{
	int select = 0;

	while (1)
	{
		printf("学生:1\n");
		printf("老师:2\n");
		scanf("%d", &select);

		if (1 == select)
		{
			Stu_initFun(STUNUM, stu);
		}
		else if (2 == select)
		{
			Tea_initFun(TEANUM, tea);
		}
		else
		{
			printf("输入非法,退出\n");
			break;
		}
		while (1)
		{
			printf("1. 显示信息\n");
			printf("2. 修改信息\n");
			printf("3. 重新选择操作对象\n");
			scanf("%d", &select);

			if (1 == select)
				printFun();   // 打印信息
			else if (2 == select)
				alterFun();
			else
			{
				break;
			}

		}
	}
	
	return 0;
}

stu.h

#pragma once
#ifndef _STU_
#define _STU_

// 定义学生结构体
typedef struct Student
{
	char name[20];	// 名字
	int stuNum;		// 学号
	float score;	// 成绩
}Stu;
// 初始化操作,向公共代码注册学生的信息
// 
// 
extern void Stu_initFun(int n, Stu buf[]);

static void Stu_print(int n, void *buf);
static void Stu_alter(int n, void *buf);

#endif

stu.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "stu.h"
#include "public.h"

static struct Register reg = { 0 };   // 初始化0

/*  功能:初始化操作,向“公共代码”注册学生的信息
*		  注册信息是:学生结构体数组 和 操作学生数据的函数
*	参数:
*		 n:   学生结构体数组的元素个数
*		 buf: 数组首元素指针
*/
void Stu_initFun(int n, Stu buf[])
{
	reg.n = n;					//学生结构体数组大小
	reg.buf = (void *)buf;		// 学生数组首元素地址,公共代码不区分类型
	reg.print = Stu_print;		// 给公共代码传递学生的打印函数指针,让公共代码回调
	reg.alter = Stu_alter;		// 修改学生数据的函数指针,让公共代码回调。

	
	registerFun(&reg);		// 向公共代码注册:即传递结构体指针,将封装的结构体传递出去。
}


static void Stu_print(int n, void *buf)
{
	int i = 0;
	Stu *stu = (Stu *)buf;

	for (i = 0; i < n; i++)
	{
		printf("%s,%d,%f\n", stu[i].name, stu[i].stuNum, stu[i].score);
	}

}

static void Stu_alter(int n, void *buf)
{
	int i = 0;
	int stuNum;
	Stu *stu = (Stu *)buf;

	printf("输入学生学号:");
	scanf("%d", &stuNum);

	for (i = 0; i < n; i++)
	{
		if (stu[i].stuNum == stuNum)
		{
			printf("%s,%d,%f\n",stu[i].name,stu[i].stuNum,stu[i].score);
			printf("输入新信息\n");
			scanf("%s,%d,%f", stu[i].name, stu[i].stuNum, stu[i].score);
			break;
		}
	}

tea.h

#pragma once
#ifndef _TEA_
#define _TEA_

typedef struct Teacher
{
	char name[20];	// 名字
	int teaNum;		// 学号
	int grade;		// 级别

}Tea;


void Tea_initFun(int n, Tea buf[]);
static void Tea_print(int n, void *tea);
static void Tea_alter(int n, void *tea);


#endif

tea.c

#define _CRT_SECURE_NO_WARNINGS
#include "tea.h"
#include "public.h"
#include <stdio.h>

static struct Register reg = { 0 };

void Tea_initFun(int n, Tea buf[])
{
	reg.n = n;
	reg.buf = (void *)buf;
	reg.print = Tea_print;
	reg.alter = Tea_alter;

	registerFun(&reg);   // 与stu 同理,向public注册
}

static void Tea_print(int n, void *buf)
{
	int i = 0;
	Tea *tea = (Tea *)buf;
	for (i = 0; i < n; i++)
	{
		printf("%s,%d,%d\n",tea[i].name,tea[i].teaNum,tea[i].grade);
	}
}



static void Tea_alter(int n, void *buf)
{
	int i = 0;
	int teaNum;
	Tea *tea = (Tea *)buf;

	printf("输入教师号: ");
	scanf("%d", &teaNum);

	for (i = 0; i < n; i++)
	{
		if (tea[i].teaNum == teaNum)
		{
			printf("%s,%d,%f\n", tea[i].name, tea[i].teaNum, tea[i].grade);
			printf("输入新信息:");
			scanf("%s,%d,%f", tea[i].name, tea[i].teaNum, tea[i].grade);
			break;
		}
	}

}

public.h

#pragma once
#ifndef _PUBLIC_
#define _PUBLIC_

struct Register
{
	void *buf;	// 数组的第一个元素
	int n;      // 数组的元素个数
	
	void(*print)();  // 定义函数指针,用于指向打印函数
	void(*alter)();  // 定义函数指针,用于指向修改函数 
};

extern void registerFun(struct Register *reginfo);
extern void printFun(void);
extern void alterFun(void);

#endif

public.c

#pragma once
#include <stdio.h>
#include "public.h"

// 保存差异代码注册的reg 结构体,结构体里面保存了差异代码的函数指针
struct Register *regp = NULL;

extern void registerFun(struct Register *reginfo)
{
	regp = reginfo;
}

extern void printFun(void)
{
	// 通过注册的reg信息,调用差异代码的显示函数
	// 如果注册的是“学生操作信息”,调用的就是学生的显示函数,
	regp->print(regp->n, regp->buf);
}
extern void alterFun(void)
{
	regp->alter(regp->n, regp->buf);
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值