函数指针学习

定义的三种方式

符号说明
void函数返回值类型
(*FUNC_TYPE2)函数指针名
(int, char)参数列表
	void func(int a , char c)
	{
	printf("hello world\n");
	}

	//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, 's');

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

函数指针数组

符号说明
*pArray[3]指针数组
pArray[i] ()函数调用
void func1()
{
	printf("func1 调用了\n");
}

void func2()
{
	printf("func2 调用了\n");
}

void func3()
{
	printf("func3 调用了\n");
}

//函数指针数组
void test02()
{
	void(*pArray[3])();

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

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

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

void printText(void * data,void(*myPrintInt)(void *))
{
	myPrintInt(data);
}
void myPrintInt(void * data)
{
	int* num = data;
	printf("%d\n", *num);
}
void test01()
{
	int a = 10;
	printText(&a,myPrintInt);
}

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

void printAllArray(void * pArray,int eleSize,int len,void(*myPrint)(void*))
{
	char* p = pArray;
	for (int i = 0; i < len; i++)
	{
		//获取数组中每个元素的首地址
		char* eleAddr = p + eleSize * i;
		//交换给用户做打印操作
		myPrint(eleAddr);
	}
}
void myPrintInt(void * data)
{
	int* num = data;
	printf("%d\n",*num);
}
void test01()
{
	int arr[5] = { 1,2,3,4,5 };
	int len = sizeof(arr) / sizeof(int);
	printAllArray(arr,sizeof(int),len,myPrintInt);
}

数组查找

  • 注意字符串比较
  • 学习用地址取值
struct Person {
	char name[64];
	int age;
};
void myPrintperson(void* data)
{
	struct Person* p = data;
	printf("姓名:%s  年龄:%d \n", p->name, p->age);
}

//查找数组中的元素是否存在
//参数1  数组首地址   参数2  每个元素的大小  参数3  数组元素个数  参数4 查找数据
int findArrayEle(void * pArray,int eleSize,int length, void *data,int(*myCompare)(void*,void*))
{
	char* p = pArray;
	for (int i = 0; i < length; i++)
	{
		//每个元素的首地址
		char* eleAddr = p + eleSize * i;
		//if ( 数组中的变量的元素 == 用户传入的元素)
		if (myCompare(eleAddr,data))
		{
			return 1;
		}

	}
	return 0;
}
int myComparePerson(void* data1, void* data2)
{
	struct Person* p1 = data1;
	struct Person* p2 = data2;

	/*if (strcmp(p1->name ,p2->name) == 0 && p1->age == p2->age)
	{
		return 1;
	}
	return 0;*/
	return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}
void test02()
{
	struct Person psersonArray[] =
	{
		{"aaa",10},
		{"bbb",20},
		{"ccc",30},
		{"ddd",40},
	};

	int length = sizeof(psersonArray) / sizeof(struct Person);
	printAllArray(psersonArray, sizeof(struct Person), length, myPrintperson);

	//查找数组中指定的元素是否存在
	struct Person p = { "ccc",30 };

	int ret = findArrayEle(psersonArray, sizeof(struct Person), length, &p, myComparePerson);
	if (ret)
	{
		printf("找到了元素\n");
	}
	else
	{
		printf("未找到\n");
	}
}

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

符号说明
selectSort对数组排序
myCompare对两个数进行比较—回调函数
memcpy对内存进行拷贝
  • 在选择排序的结构下,将两个数的比较交给函数来实现。因为对数组的类型是不确定的。

  • selectSort函数的四个参数

    • pAddr ——数组地址
    • elesize —— 元素大小
    • length —— 数组长度
    • myCompare ——数组指针
void selectSort(void * pAddr,int elesize,int length,int(*myCompare)(void*,void*))
{
	char* temp = malloc(elesize);

	for (int i = 0; i < length; i++)
	{
		int minOrMax = i;//定义最小值 或者 最大值 下标
		for (int j = i+1; j < length; j++)
		{
			//定义出 j元素地址
			char* pJ = (char*)pAddr + elesize * j;
			char *pMinOrMax = (char*)pAddr + elesize * minOrMax;

			//if (pAddr[j]<pAddr[minOrMax]) 
			//void类型是不能比较大小的

			if (myCompare(pJ,pMinOrMax))
			{
				minOrMax = j;//更新最小值或者最大值下标
			}	
		}

		if (i != minOrMax)
		{
			//交换i和minOrMax 下标元素
			char* pI = (char*)pAddr + elesize * i;
			char* pMinOrMax = (char*)pAddr + elesize * minOrMax;

			
			memcpy(temp, pI, elesize);
			memcpy(pI, pMinOrMax, elesize);
			memcpy(pMinOrMax, temp, elesize);
		}


	}
	if (temp != NULL)
	{
		free(temp);
		temp = NULL;
	}
}

int myCompareInt(void* data1,void * data2)
{
	int* num1 = data1;
	int* num2 = data2;

	if (*num1 > *num2)
	{
		return 1;
	}
	return 0;
}

void test01()
{
	int arr[] = { 10,30,20,60,50,40 };
	
	int length = sizeof(arr) / sizeof(int);
	selectSort(arr,sizeof(int),length, myCompareInt);

	for (int i = 0; i < length; i++)
	{
		printf("%d\n", arr[i]);
	}
}

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

int myComparePerson(void* data1, void* data2)
{
	struct Person* p1 = data1;
	struct Person* p2 = data2;

	/*if (p1->age < p2->age)
	{
		return 1;
	}
	return 0;*/

	//按照年龄 升序排序
	return p1->age < p2->age;
}
void test02()
{
	struct Person pArray[] =
	{
		{"aaa",10},
		{"bbb",50},
		{"ccc",30},
		{"ddd",40},
	};

	int length = sizeof(pArray) / sizeof(struct Person);
	selectSort(pArray, sizeof(struct Person), length, myComparePerson);

	for (int i = 0; i < length; i++)
	{
		printf("姓名:%s  年龄:%d\n", pArray[i].name, pArray[i].age);
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值