您好,欢迎来到年旅网。
搜索
您的当前位置:首页【C语言】指针的高级用法(指针数组,函数指针,函数指针数组,回调函数)

【C语言】指针的高级用法(指针数组,函数指针,函数指针数组,回调函数)

来源:年旅网

前言

一.指针数组

数组大家都知道,数组是用来存储一组相同类型数据的集合,例如有:整形数组字符型数组双精度度浮点型数组。那么指针数组是什么呢,指针数组就是一组存放指针类型的集合。如下图所示。

 

那么数组指针有什么用呢?下面会介绍到

二.函数指针

答案是使用函数指针。 

函数指针用法如上, 各个位置的意义如下。

1.函数指针的使用。

#include<stdio.h>

int Add(int x, int y)
{
	return x + y;
}

int main()
{
	int ret1 = Add(1, 2);
	printf("%d\n", ret1);//常规用法

	int (*pAdd)(int, int) = &Add;//使用函数指针的用法
	int ret2 = pAdd(2, 3);
	printf("%d\n", ret2);

	return 0;
}

2.typedef函数指针的使用

在我们使用函数指针的使用需要很长的定义,这个时候我们可以使用typedef关键字来缩短代码长度。 

#include<stdio.h>

typedef int(*p_fun)(int, int);//使用typedef关键字简化代码长度

int Add(int x, int y)
{
	return x + y;
}

int main()
{
	int ret1 = Add(1, 2);
	printf("%d\n", ret1);//常规用法

	int (*pAdd)(int, int) = &Add;//使用函数指针的用法
	int ret2 = pAdd(2, 3);
	printf("%d\n", ret2);

	p_fun pAdd2 = &Add;//使用typedef的用法。
	int ret3 = pAdd2(3, 4);
	printf("%d\n", ret3);

	return 0;
}

 

也就是说,使用typedef重定义后,int (*pAdd)(int,int)等同于p_fun pAdd。 

三.函数指针数组

1.函数指针数组的定义 

那么函数指针数组如何定义呢?如下所示。

2.计算器的一般实现

函数指针数组的用途。 

#include<stdio.h>

int Add(int x, int y)
{
	return x + y;
}

int Sub(int x, int y)
{
	return x - y;
}

int Mul(int x, int y)
{
	return x * y;
}

int Div(int x, int y)
{
	return x / y;
}

void menu()
{
	printf("		1.加法  2.减法	 \n");
	printf("		3.乘法  4.除法	 \n");
	printf("		  0.退出程序  	 \n");
}

int main()
{
	int input = 0;
	int x, y;
	do
	{
		menu();
		printf("请输入操作:");
		scanf("%d", &input);

		switch (input)
		{
		case 1:
			printf("请输入两个数:");
			scanf("%d %d", &x, &y);
			int ret = Add(x, y);
			printf("%d\n", ret);
			break;
		case 2:
			printf("请输入两个数:");
			scanf("%d %d", &x, &y);
			ret = Sub(x, y);
			printf("%d\n", ret);
			break;
		case 3:
			printf("请输入两个数:");
			scanf("%d %d", &x, &y);
			ret = Mul(x, y);
			printf("%d\n", ret);
			break;
		case 4:
			printf("请输入两个数:");
			scanf("%d %d", &x, &y);
			ret = Div(x, y);
			printf("%d\n", ret);
			break;
		case 0:
			break;
		default:
			printf("输入错误,请重新输入\n");
			continue;
		}

	} while (input);
	return 0;
}

通过这种实现的方法,代码非常臃肿,有许多相似或者是重复的地方。使用转移表来实现,可以大大的简化代码。 

 3.计算器的转移表实现

#include<stdio.h>

int Add(int x, int y)
{
	return x + y;
}

int Sub(int x, int y)
{
	return x - y;
}

int Mul(int x, int y)
{
	return x * y;
}

int Div(int x, int y)
{
	return x / y;
}

void menu()
{
	printf("		1.加法  2.减法	 \n");
	printf("		3.乘法  4.除法	 \n");
	printf("		  0.退出程序  	 \n");
}

int main()
{
	int (*parr[4])(int, int) = { &Add,&Sub,&Mul,&Div };
	int input = 0;
	do
	{
		menu();
		printf("请输入你的操作:");
		scanf("%d", &input);

		if (input == 0)
		{
			break;
		}
		else if (input >= 1 && input <= 4)
		{
			int x, y;
			printf("请输入两个数:");
			scanf("%d %d", &x, &y);
			int ret = parr[input - 1](x, y);
			printf("%d\n", ret);
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}

	} while (input);

	return 0;
}

四. 回调函数

什么叫回调函数,回调函数就是通过函数指针调用的函数。

回调函数的使用举例:在C语言标准库中,有一个用于快速排序的库函数,这个库函数就有用到回调函数,下面来举例。 

 void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));

这个qsort库函数的函数参数有四个,分别是:需要排序的数组该数组的总字节大小每个元素的大小以及一个compare比较函数,其中这个compare比较函数需要自己设计。原因:qsort这个库函数不知道你需要排序的数据类型有可能int,char,甚至有可能是一个结构体数组,因为这个原因,所以我们需要自己设计一个compare比较函数来帮助qsort完成排序,其中compare函数就是你需要排什么类型数据来设计。

#include<stdio.h>

int Compare(void* p1, void* p2)//用于qsort函数的比较函数
{
	return *(int*)p1 - *(int*)p2;
}

void Print(int* parr, int sz)//打印数组
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", parr[i]);
	}
	printf("\n");
}

int main()
{
	int arr[] = { 10,8,6,47,52,10,23,69,74 };
	Print(arr, sizeof(arr) / sizeof(arr[0]));

	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), Compare);//使用qsort函数对数组进行排序
	Print(arr, sizeof(arr) / sizeof(arr[0]));

	return 0;
}

1.使用冒泡排序算法来模拟实现qosrt函数 

#include<stdio.h>

typedef struct Stu
{
	char name[20];
	int age;
}Stu;

void Swap(void* p1, void* p2, int sz)//交换函数,一个字节一个字节的交换
{
	for (int i = 0; i < sz; i++)
	{
		char tmp = *((char*)p1 + i);
		*((char*)p1 + i) = *((char*)p2 + i);
		*((char*)p2 + i) = tmp;
	}
}

void Bubble_Sort(void* arr, int num, int sz, int (*Compare)(void*, void*))//使用冒泡排序模拟回调函数
{	
	for (int i = num; i > 0; i--)
	{
		for (int j = 0; j < i - 1; j++)
		{
			if (Compare((char*)(arr)+j * sz, (char*)(arr)+(j + 1) * sz)>0)
			{
				Swap((char*)(arr)+j * sz, (char*)(arr)+(j + 1) * sz, sz);
			}
		}
	}
}

int Compare1(void* p1, void* p2)//按年龄来排序
{
	return ((Stu*)p1)->age - ((Stu*)p1)->age;
}

int Compare2(void* p1, void* p2)//按名字来排序
{
	return strcmp(((Stu*)p1)->name, ((Stu*)p2)->name);
}

int main()
{
	Stu arr[] = { {"张三",18},{"李四",19},{"王五",20} };
	int num = sizeof(arr) / sizeof(arr[0]);

	for (int i = 0; i < num; i++)
	{
		printf("%s %d\n", arr[i].name, arr[i].age);
	}

	Bubble_Sort(arr, num, sizeof(arr[0]), Compare2);

	for (int i = 0; i < num; i++)
	{
		printf("%s %d\n", arr[i].name, arr[i].age);
	}

	return 0;
}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务