设计模式-结构体函数指针

1 代码

1.1 Makefile

Code
TARGET = pointer
CC=gcc
DIR = $(shell pwd)
DIR_OBJ = $(DIR)/obj
DIR_SRC = $(DIR)/src
DIR_INC = $(DIR)/inc
SRC = $(wildcard $(DIR_SRC)/*.c)
SRC_NO_DIR = $(notdir $(SRC))
SRC_OBJ = $(patsubst %c, %o, $(SRC_NO_DIR))
INC = -I$(DIR_INC) \
FLAG = -g
all:$(TARGET) 
	@echo "=======  All make successs  ======="
$(TARGET):$(addprefix $(DIR_OBJ)/, $(SRC_OBJ))
	$(CC) -o $@ $^ $(INC) $(FLAG)
	@echo "======= Linux make successs ======="
$(DIR_OBJ)/%.o:$(DIR_SRC)/%.c
	@mkdir -p $(DIR_OBJ)
	$(CC) -c $< -o $@ $(INC) $(FLAG)
.PHONY:clean
clean:
	-rm -rf $(DIR_OBJ)
	-rm $(TARGET) 
	@echo "======= make clean success ======="

1.2 方法一:结构体定义时,初始化函数

Code

int func1(char n)
{
	//n = 2;
	printf("hello n=%d\n", n);
}
int func2(void)
{
	printf("hello 2\n");
}
struct ops_1
{
	int (*func1)(char n);
	int (*func2)(void);
};
void main_func_1(void)
{
	struct ops_1 m;
	struct ops_1 *mi_ops = &m;
	//mi_ops.func1(2);	// 失败
	//mi_ops.func2();	// 失败
	m.func2 = func2;
	m.func1 = func1;
	mi_ops->func1(3);
	mi_ops->func2();
	struct ops_1 p = {
		//func1 = func1,	// 失败
		//func2 = func2,	// 失败
		func1,
		func2,
	};
	p.func1(11);
	p.func2();
}

1.3 方法二:结构体定义时,初始化函数

Code
int add_2(int a, int b)
{
	return a + b;
}
struct ops_2
{
	int (*func)(int, int);
};
void main_func_2(void)
{
	struct ops_2 m;
	struct ops_2 *mi_ops = &m;
	mi_ops->func = add_2;
	printf("add = %d\n", mi_ops->func(2, 3));
}

1.4 方法三:结构体中指向函数的指针

Code
typedef struct std
{
	void (*init)(void);
}stu;
void init(void)
{
	printf("hello init\n");
}
void main_func_3(void)
{
	stu *pt;
	pt = (stu *)malloc(sizeof(stu));
	pt->init = init;
	pt->init();
	free(pt);
}

1.5 方法四:注册回调函数的使用方法

Code

typedef struct stud
{
	int a;
	void (*pshow)(int);
}TMP;
void func_4(TMP *tmp)
{
	if (tmp->a > 3)
	{
		(tmp->pshow)(tmp->a);
	}
}
void show(int n)
{
	printf("a4 = %d\n", n);
}
void main_func_4(void)
{
	TMP p;
	p.a = 5;
	p.pshow = show;
	func_4(&p);
}

1.5 方法五:函数指针实现回调函数

Code

int func_A(char *str)
{
	printf("---A---:%s\n", str);
	return 0;
}
int callback_5(char *p, int (*ptr)(char *))
{
	printf("callback\n");
	(*ptr)(p);
	return 0;
}
void main_func_5(void)
{
	char *p = "Hello World";
	// 直接调用函数方法
	func_A(p);
	// 函数指针调用指定函数的方法
	(*func_A)(p);
	// 回调函数方法
	callback_5(p, func_A);
}

1.6 :回调函数实例

Code

/****************************************
 * 函数指针结构体
 ***************************************/
typedef struct _OP {
    float (*p_add)(float, float); 
    float (*p_sub)(float, float); 
    float (*p_mul)(float, float); 
    float (*p_div)(float, float); 
} OP; 
/****************************************
 * 加减乘除函数
 ***************************************/
float ADD(float a, float b) 
{
    return a + b;
}
float SUB(float a, float b) 
{
    return a - b;
}
float MUL(float a, float b) 
{
    return a * b;
}
float DIV(float a, float b) 
{
    return a / b;
}
/****************************************
 * 初始化函数指针
 ***************************************/
void init_op(OP *op)
{
    op->p_add = ADD;
    op->p_sub = SUB;
    op->p_mul = &MUL;
    op->p_div = &DIV;
}
/****************************************
 * 库函数
 ***************************************/
float add_sub_mul_div(float a, float b, float (*op_func)(float, float))
{
    return (*op_func)(a, b);
}
/****************************************
 * 示例主函数
 ***************************************/
int main_func_op(void) 
{
    OP *op = (OP *)malloc(sizeof(OP)); 
    init_op(op);
    /* 直接使用函数指针调用函数 */ 
    printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f\n", 
		(op->p_add)(1.3, 2.2), 
		(*op->p_sub)(1.3, 2.2), 
		(op->p_mul)(1.3, 2.2), 
		(*op->p_div)(1.3, 2.2));
    /* 调用回调函数 */ 
    printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f\n", 
		add_sub_mul_div(1.3, 2.2, ADD), 
		add_sub_mul_div(1.3, 2.2, SUB), 
		add_sub_mul_div(1.3, 2.2, MUL), 
		add_sub_mul_div(1.3, 2.2, DIV));
    return 0; 
}

函数指针基础教学

// 1.函数定义
/* 方法1 */
void (*p_func)(int, int, float) = NULL;
/* 方法2 */
typedef void (*tp_func)(int, int, float);
tp_func p_func = NULL;

// 2.函数指针的赋值
void (*p_func)(int, int, float) = NULL;
/* 方法1 */
p_func = &func1;
/* 方法2 */
p_func = func2;

// 3.使用函数指针调用函数
/* 方法1 */
int val1 = p_func(1,2,3.0);
/* 方法2 */
int val2 = (*p_func)(1,2,3.0);

// 4.函数指针作为参数进行传值
/* func3 将函数指针 p_func 作为其形参 */
void func3(int a, int b, float c, void (*p_func)(int, int, float))
{
	(*p_func)(a, b, c);
}
/* func4 调用函数func3 */
void func4()
{
	func3(1, 2, 3.0, func_1);
	/* 或者 func3(1, 2, 3.0, &func_1); */
}

// 5.函数指针作为函数返回类型
void (* func5(int, int, float ))(int, int)
{
	
}

// 6.函数指针数组
// 定义了一个元素个数为5,类型是 void (*)(int, int, float) 的函数指针数组。
/* 方法1 */
void (*func_array_1[5])(int, int, float);
/* 方法2 */
typedef void (*p_func_array)(int, int, float);
p_func_array func_array_2[5];

参考链接

posted @ 2024-02-20 10:39  starc再起航  阅读(5)  评论(0编辑  收藏  举报