函数指针和回调函数2
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;
}