高级指针之回调函数

1. 学习来源

哔哩哔哩“C提高教程”(https://www.bilibili.com/video/BV18y4y1H7pt?p=62)学习总结.

2. 数组指针的定义方式

//1、先定义出数组的类型,再定义数组指针变量
	int arr[] = { 1, 2, 3, 4, 5 };
	typedef int(ARRAY_TYPE)[5]; //ARRAY_TYPE是一个数据类型,存放5个int元素的数组的类型
	ARRAY_TYPE * arrP = &arr; //arrP就是数组指针
	// *arrP 是 arr
//2、先定义数组指针的类型,再定义数组指针变量 	
	typedef int(*ARRAY_TYPE)[5];
	// *arrP 是 arr
	ARRAY_TYPE arrP = &arr;
//3、直接定义数组指针变量
	int arr[] = { 1, 2, 3, 4, 5 };
	int(*p)[5]  = &arr;
	//*p -> arr

3. 函数指针定义

	//1、先定义函数类型,通过函数类型定义函数指针变量
	typedef void(FUNC_TYPE)(int,char);
	FUNC_TYPE * pFunc = func;
	pFunc(10,'a');

	//2、先定义函数指针类型,再通过函数指针类型定义函数指针变量
	typedef void(*FUNC_TYPE2) (int, char);
	FUNC_TYPE2 pFunc2 = func;
	pFunc2(10, 'a');

	//3、直接定义函数指针变量
	void(*pFunc3)(int, char) = func;
	pFunc3(10, 'a');

	//4、函数指针 和 指针函数区别
	//函数指针是指向函数的指针;
 	//指针函数是返回类型为指针的函数;
 	
 	//函数指针数组
	void(*fun_array[3])();

	fun_array[0] = func1;
	fun_array[1] = func2;
	fun_array[2] = func3;

	for (int i = 0; i < 3;i++)
	{
		fun_array[i]();
	}

4. 回调函数案例

**用户把一个函数指针作为参数传递为其他函数,后者将“回调”用户的函数。**

提供一个函数,可以打印任意类型的数组

//CallBack1.h
#pragma once
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

struct Person
{
	char name[60];
	int age;
};

//通用程序设计模块
void printAll(void *data, int len, int elesize, void(*func)(void*))
{
	char *p = data;
	for (int i = 0; i < len; i++)
	{
		char *elead = p + elesize * i;    //获取数组中每个元素的首地址
		func(elead);
	}
	
}


//回调函数-打印任意类型数组
void CallBack(void *data)
{
	int *p = data;
	printf("%d\n", *p);
}

//回调函数-打印任意类型结构体数组
void CallBack1(void *data)
{
	struct Person *p1 = data;
	printf("name=%s,age=%d\n", p1->name, p1->age);
}

查找数组中的元素是否存在

// CallBack2.h
#pragma once
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

struct Person1
{
	char name[20];
	int age;
};

//利用回调函数查找数组中的元素是否存在
int findValue(void *arr, int len, int ele_size,int(*func)(void *, void *),void *data)
{
	char *p = arr;
	for (int i = 0; i < len; i++)
	{
		char *p1 = p + ele_size * i;
		if (func(p1, data))
		{
			return 1;
		}
	}
	return 0;

}

//回调函数
int CallBack3(void *data, void *data1)
{
	int *p1 = data;
	int *p2 = data1;
	if (*p1 == *p2)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

//结构体数组中查找的回调函数
int CallBack4(void *data, void *data1)
{
	struct Person1 *p1 = data;
	struct Person1 *p2 = data1;
	if (strcmp(p1->name,p2->name)==0&&p1->age==p2->age)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

对任意类型的数组进行排序

// CallBack3.h
#pragma once
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

//系统设计模块
void bbsort(void *bbrr, int bb_len, int bb_size,int (*func)(void *,void *) )
{
	char *temp = malloc(bb_size);
	for (int i = 0; i < bb_len; i++)
	{
		for (int j = 0; j < bb_len - i - 1; j++)
		{
			char *jplus = (char*)bbrr + bb_size * (j + 1);
			char *jb = (char*)bbrr + bb_size * (j);
			if (func(jplus, jb))
			{
				memcpy(temp, jplus, bb_size);
				memcpy(jplus, jb, bb_size);
				memcpy(jb, temp, bb_size);
			}
		}
	}
	if (temp != NULL)
	{
		free(temp);
		temp = NULL;
	}
}


//回调函数模块
int CallBack5(void *jplus, void *jb)
{
	int *num = jplus;
	int *num1 = jb;
	if (*num > *num1)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

测试主函数

// main.c
#include"CallBack1.h"
#include"CallBack2.h"
#include"CallBack3.h"

int main()
{

	//利用回调函数打印任意类型的数组
	int arr[] = { 0,1,2,3,4,5,6,7,8,9 };

	int len = sizeof(arr) / sizeof(int);
	int elesize = sizeof(int);
	printAll(arr, len, elesize, CallBack);

	//利用回调函数打印结构体数组
	struct Person p1Arr[] = {
		{"aaa",20},
		{"bbb",30},
		{"ccc",40},
		{"ddd",50}
	};
	int len1 = sizeof(p1Arr) / sizeof(struct Person);
	int elesize1 = sizeof(struct Person);
	//printf("%d,%d", len1, elesize1);
	printAll(p1Arr, len1, elesize1, CallBack1);

	int aarr[] = { 0,1,2,3,4,5,6 };
	int num = 3;
	int aarr_len = sizeof(aarr) / sizeof(int);
	int aarr_size = sizeof(int);
	//查找任意数组中的元素是否存在
	int result= findValue(aarr, aarr_len, aarr_size, CallBack3,&num);

	if (result == 1)
	{
		printf("找到了文件!");
	}
	else
	{
		printf("没有找到文件!");
	}

	//利用回调函数在结构体数组中查找任意类型元素
	struct Person1 p1[4] = {
		{"aaa",12},
		{"bbb",17},
		{"ccc",18},
		{"ddd",19},
	};
	int p1_len = sizeof(p1) / sizeof(struct Person1);
	int p1_size = sizeof(struct Person1);
	struct Person1 ppx = { "aaa",12 };
	int result1 = findValue(p1, p1_len, p1_size, CallBack4, &ppx);
	if (result1 == 1)
	{
		printf("找到了文件!\n");
	}
	else
	{
		printf("没有找到文件!\n");
	}
	printf("对任意类型的数组进行排序\n");
	int bbrr[] = { 1,5,9,15,2,656,45,4,215,45,1,2, };
	int bb_len = sizeof(bbrr) / sizeof(int);
	int bb_size = sizeof(int);
	bbsort(bbrr, bb_len, bb_size, CallBack5);

	for (int i = 0; i < bb_len; i++)
	{
		printf("%d ", bbrr[i]);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值