C语言 函数指针做函数参数(回调函数)

  • 利用回调函数实现打印任意类型数据

    • 实现打印int型数据

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

//将打印需求交给用户
void myPrintInt(void *data){
	int *p = data;
	printf("%d\n", *p);	
}

void printText(void *data, void(*myPrint)(void *)){
	myPrint(data);
}

//打印int型数据
void test01(){
	int a = 10;
	printText(&a, myPrintInt);
}
  • 实现打印结构体类型数据

//结构体类型
struct Person{
	char name[1024];
	int age;
};

void printText(void *data, void(*myPrint)(void *)){
	myPrint(data);
}
//用户编写
void myPrintStruct(void *data){
	struct Person *p = data;
	printf("name = %s age = %d\n", p->name, p->age);
}
//打印结构体 
void test02(){
	struct Person person = {
		 "Bob", 10
	};
	printText(&person, myPrintStruct);
}

  • 利用回调函数实现打印任意类型数组

    • 实现打印int型数组

void printArray(void *nums,int eleSize,  int len, void(*myPrint)(void *)){
	char *p = nums; 
	int i = 0;
	for(i = 0; i < len; i++){
		char *eleAddr = p + eleSize * i;//找到每个元素的起始地址
	
		//将打印操作交还给用户 
		//printf("%d\n", nums[i]);
        myPrint(eleAddr);

	}
}
//用户自定义打印操作
void myPrintIntArray(void *data){
	int *p = data;
	printf("%d\n", *p);
}

void test03(){
	int nums[] = {1,2,3,4,5};
	int len = sizeof(nums) / sizeof(int);
	printArray(nums,sizeof(int), len, myPrintIntArray);
}
  • 实现打印结构体类型数组

//结构体类型
struct Person{
	char name[1024];
	int age;
};
//打印任意类型数组的函数
void printArray(void *nums,int eleSize,  int len, void(*myPrint)(void *)){
	char *p = nums; 
	int i = 0;
	for(i = 0; i < len; i++){
		char *eleAddr = p + eleSize * i;//找到每个元素起始地址
		
		//将打印操作交还给用户 
		//printf("%d\n", nums[i]);
        myPrint(eleAddr);
	}
}
//用户自定义打印操作
void myPrintStructArr(void *data){
	struct Person *p = data;
	printf("%s, %d\n", p->name, p->age);
}
    
void test04(){
	struct Person person[] = {
		{"aaa", 10},
		{"bbb", 20},
		{"ccc", 30},
		{"ddd", 40},
	};
	int len = sizeof(person) / sizeof(struct Person);
	printArray(person, sizeof(struct Person), len, myPrintStructArr);
}

  • 实现查找结构体类型功能

//结构体类型 
struct Person{
	char name[1024];
	int age;
};
//实现查找功能
void findEle(void *pArray, void *data, int eleSize, int len, int(*compare)(void *, void *)){
	char *p = pArray;
	int i = 0;
	int ret = -1;
	for(i = 0; i < len; i++){
		char *eleAddr = p + eleSize * i;//查找每个元素的起始地址
		//查到该元素 
		if(compare(eleAddr, data) == 0){
			ret = 0;
		}
	}
	if(ret == 0){
		printf("数组中包含该元素!");
	}else{
		printf("数组中不包含该元素!");
	}
	
}
//两个元素相比较,相同为0,相异为-1 
int compare(void *data1, void *data2){
	struct Person *p1 = data1;
	struct Person *p2 = data2;
	if(strcmp(p1->name, p2->name) == 0 && p1->age == p2->age){
		return 0;
	}
	return -1;
}
void test05(){
	struct Person person[] = {
		{"aaa", 10},
		{"bbb", 20},
		{"ccc", 30},
		{"ddd", 40},
	};
	struct Person p = {
		"ccc", 30
	};
	int len = sizeof(person) / sizeof(struct Person);
	findEle(person, &p, sizeof(struct Person), len, compare);
}
  • 提供一个函数,实现对任意类型的数组进行排序,排序规则利用选择排序,排序的顺序由用户自己指定

    • 对int型数组进行排序

//由用户给出,确定排序顺序
int sortRule01 (void *data1, void *data2){
	int *p1 = data1;
	int *p2 = data2;
	
	if(*p1 > *p2){
		return 1;
	} else if(*p1 < *p2){
		return -1;
	}else{
		return 0;
	}
}
//实现各种类型排序功能,用选择排序实现
void sortArray(void *pArray, int eleSize, int len, int(*sortRule)(void *, void *)){
	char * temp = malloc(eleSize);
	char *p = pArray;
	int i = 0, j = 0;
	for(i = 0; i < len; i++){
		int minOrMax = i;
		for(j = i + 1; j < len; j++){
			//pArray[minOrMax] > pArray[j]     1
			//pArray[minOrMax] < pArray[j]     -1
			//pArray[minOrMax] = pArray[j]     0
			char *minOrMaxEle = p + eleSize * minOrMax;//找到最大或者最小那个元素的起始地址
			char *curEle = p + eleSize * j;//找到当前元素的起始地址
			if(sortRule(minOrMaxEle, curEle) == 1){
				minOrMax= j;
			}
		}
        //如果最大或者最小值有变化,那么需要进行交换,将最大或者最小值放到前边
		if(minOrMax != i){
			
			char *indexMinOrMaxEle = p + eleSize * minOrMax;
			char *indexIEle = p + eleSize * i;
			
			memcpy(temp, indexMinOrMaxEle, eleSize);
			memcpy(indexMinOrMaxEle, indexIEle, eleSize);
			memcpy(indexIEle, temp, eleSize);
		}
	}
	if (temp != NULL)
	{
		free(temp);
		temp = NULL;
	}
}
//用户自定义实现打印函数
void myPrint01(void *data){
	int *p = data;
	printf("%d ", *p);
}
//实现打印各种数据类型
void display(void *pArray,int eleSize, int len, void(*myPrint)(void *)){
	char *p = pArray;
	int i = 0;
	for(i = 0; i < len; i++){
		char *eleAddr = p + eleSize * i;
		myPrint(eleAddr);
		//printf("%d ", nums[i]);
	}
}

void test06(){
	int nums[] = {6,8,4,10,1};
	int len = sizeof(nums) / sizeof(int);
	sortArray(nums, sizeof(int), len, sortRule01);
	display(nums,sizeof(int), len, myPrint01);	
}
  • 对结构体类型进行排序

    //结构体类型 
    struct Person{
    	char name[1024];
    	int age;
    };
    //实现各种类型排序功能,用选择排序实现
    void sortArray(void *pArray, int eleSize, int len, int(*sortRule)(void *, void *)){
    	char * temp = malloc(eleSize);
    	char *p = pArray;
    	int i = 0, j = 0;
    	for(i = 0; i < len; i++){
    		int minOrMax = i;
    		for(j = i + 1; j < len; j++){
    			//pArray[minOrMax] > pArray[j]     1
    			//pArray[minOrMax] < pArray[j]     -1
    			//pArray[minOrMax] = pArray[j]     0
    			char *minOrMaxEle = p + eleSize * minOrMax;//找到最大或者最小那个元素的起始地址
    			char *curEle = p + eleSize * j;//找到当前元素的起始地址
    			if(sortRule(minOrMaxEle, curEle) == 1){
    				minOrMax= j;
    			}
    		}
            //如果最大或者最小值有变化,那么需要进行交换,将最大或者最小值放到前边
    		if(minOrMax != i){
    			
    			char *indexMinOrMaxEle = p + eleSize * minOrMax;//获取原来标记的最大或者最小值的起始地址
    			char *indexIEle = p + eleSize * i;//获取真正最大或者最小的地址
    			//进行交换
    			memcpy(temp, indexMinOrMaxEle, eleSize);
    			memcpy(indexMinOrMaxEle, indexIEle, eleSize);
    			memcpy(indexIEle, temp, eleSize);
    		}
    	}
    	if (temp != NULL)
    	{
    		free(temp);
    		temp = NULL;
    	}
    }
    //实现对各种数据类型进行打印
    void display(void *pArray,int eleSize, int len, void(*myPrint)(void *)){
    	char *p = pArray;
    	int i = 0;
    	for(i = 0; i < len; i++){
    		char *eleAddr = p + eleSize * i;
    		myPrint(eleAddr);
    		//printf("%d ", nums[i]);
    	}
    }
    //用户自定义打印操作
    void myPrint02(void *data){
    	struct	Person *p = data;
    	printf("name = %s age = %d\n", p->name, p->age);
    }
    //用户自定义排序操作,根据age的大小来进行排序
    int sortRule02 (void *data1, void *data2){
    	struct Person *p1 = data1;
    	struct Person *p2 = data2;
    	
    	if(p1->age > p2->age){
    		return 1;
    	} else if(p1->age < p2->age){
    		return -1;
    	}else{
    		return 0;
    	}
    }
    void test07(){
    	struct Person person1[] = {
    		{"aaa", 6},
    		{"bbb", 8},
    		{"ccc", 4},
    		{"ddd", 10},
    		{"eee", 1}
    	};
    	int len = sizeof(person1) / sizeof(struct Person);
    	sortArray(person1, sizeof(struct Person), len, sortRule02);
    	display(person1, sizeof(struct Person), len, myPrint02);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值