C Language--Advanced Pointers 2

Table of contents

Preface

1. Array of function pointers

2. Pointer to array of function pointers

3. Callback function

Case 1:

Case 2: qsort


Preface

        ​ ​ ​ Continuing from the previous article, I have already shared in the previous article (character pointers, pointer arrays, array pointers, array and pointer parameters, and function pointers). Today I will share with you the new content of pointers.

1. Array of function pointers

An array is a storage space that stores data of the same type. We have already learned about pointer arrays,
For example:

int *arr[10];
//数组的每个元素是int*

Then we need to store the address of the function in an array. Then this array is called an array of function pointers. How to define the array of function pointers?

int (*parr1[10])();
int *parr2[10]();
int (*)() parr3[10];

The answer is: parr1
Parr1 is first combined with [] to indicate that parr1 is an array. What is the content of the array?
is a function pointer of type int (*)().

Purpose of function pointer array:Transfer table
Example:(calculator)

Function pointer method implementation:

#include <stdio.h>
int add(int a, int b)
{
	return a + b;
}
int sub(int a, int b)
{
	return a - b;
}
int mul(int a, int b)
{
	return a * b;
}
int div(int a, int b)
{
	return a / b;
}
int main()
{
	int x, y;
	int input = 1;
	int ret = 0;
	int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
	while (input)
	{
		printf("*************************\n");
		printf(" 1:add 2:sub \n");
		printf(" 3:mul 4:div \n");
		printf("*************************\n");
		printf("请选择:");
		scanf("%d", &input);
		if ((input <= 4 && input >= 1))
		{
			printf("输入操作数:");
			scanf("%d %d", &x, &y);
			ret = (*p[input])(x, y);
		}
		else
			printf("输入有误\n");
		printf("ret = %d\n", ret);
	}
	return 0;
}

Although this writing method is clever, it also has drawbacks. The addition, subtraction, multiplication and division in functions support the same type.

2. Pointer to array of function pointers

The pointer to the array of function pointers is apointer
The pointer points to an array< a i=4>, the elements of the array are allfunction pointers;
How to define?

void test(const char* str)
{
	printf("%s\n", str);
}
int main()
{
	//函数指针pfun
	void (*pfun)(const char*) = test;
	//函数指针的数组pfunArr
	void (*pfunArr[5])(const char* str);
	pfunArr[0] = test;
	//指向函数指针数组pfunArr的指针ppfunArr
	void (*(*ppfunArr)[5])(const char*) = &pfunArr;
	return 0;
}

3. Callback function

        The callback function is a function called through a function pointer. If you pass a function pointer (address) as a parameter to another function, when this pointer is used to call the function it points to, we Just say this is a callback function. The callback function is not called directly by the implementer of the function, but is called by another party whenspecific events or conditions occur. It is used to respond to Respond to the event or condition.

Case 1:

General writing calculator

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;
}
int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入2个操作数:");
			scanf("%d %d", &x, &y);
			ret = Add(x, y);
			printf("ret = %d\n", ret);
			break;
		case 2:
			printf("请输入2个操作数:");
			scanf("%d %d", &x, &y);
			ret = Sub(x, y);
			printf("ret = %d\n", ret);
			break;
		case 3:
			printf("请输入2个操作数:");
			scanf("%d %d", &x, &y);
			ret = Mul(x, y);
			printf("ret = %d\n", ret);
			break;
		case 4:
			printf("请输入2个操作数:");
			scanf("%d %d", &x, &y);
			ret = Div(x, y);
			printf("ret = %d\n", ret);
			break;
		case 0:
			printf("退出计算器\n");
			break;
		default:
			printf("选择错误, 重新选择\n");
			break;
		}
	} while (input);

	return 0;
}

We can see that the code in each case is the same, the only difference is that the function to be called is different. Is there any way to encapsulate the code in the case into a function? This requires the knowledge of callback functions,functions called through function pointers.

Writing method:

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 calc(int (*pf)(int,int))
{
	int x = 0;
	int y = 0;
	int ret = 0;
	printf("请输入2个操作数:");
	scanf("%d %d", &x, &y);
	ret = pf(x, y);
	printf("ret = %d\n", ret);
}

int main()
{
	int input = 0;

	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			calc(Add);
			break;
		case 2:
			calc(Sub);
			break;
		case 3:
			calc(Mul);
			break;
		case 4:
			calc(Div);
			break;
		case 0:
			printf("退出计算器\n");
			break;
		default:
			printf("选择错误, 重新选择\n");
			break;
		}
	} while (input);

	return 0;
}

You can see that a calc is created, which is a function pointer that calls the function we need. Implement callbacks. calc is like a transfer station

Example 2:qsort

#include <stdlib.h>
void qsort(void* base, //待排序数组的第一个元素的地址
	       size_t num, //待排序数组的元素个数
	       size_t size,//待排序数组中一个元素的大小
	       int (* cmp)(const void* e1, const void* e2)//函数指针-cmp指向了一个函数,这个函数是用来比较两个元素的
         //e1和e2中存放的是需要比较的两个元素的地址
          );

This library function is a sorting function and includes the header file #include <stdlib.h>. Why is the parameter of function pointer cmp void*?

This function pointer is used to call a function that compares parameter sizes. In order to compare any parameters, void* is used to receive it.

Notice:

        Pointers of void* type - dereference operators cannot be used, and +- integer operations cannot be performed.

        Pointers of type void* are used to store addresses of any type of data

        VOID* No specific type of pointer

Usage examples:

#include <stdio.h>
#include <stdlib.h>
void print_arr(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

int cmp_int(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;
}

//测试qsort排序整型数据
void test1()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	print_arr(arr, sz);
	qsort(arr, sz, sizeof(arr[0]), cmp_int);
	print_arr(arr, sz);
}

 The fourth parameter of qsort needs to be created by yourself.

Use qsort to sort structures:

1. Comparison by age

int cmp_stu_by_age(const void* e1, const void* e2)
{
	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}

void test1()
{
	struct Stu arr[] = { {"zhanhsan", 20}, {"lisi", 30}, {"wangwu", 12}};
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);
}

2. Compare by name

int cmp_stu_by_name(const void* e1, const void* e2)
{
	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}

void test3()
{
	struct Stu arr[] = { {"zhanhsan", 20}, {"lisi", 30}, {"wangwu", 12} };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
}

Summary: The sorting structure only needs to cast the received parameters into the structure type.

Thank you for reading, I hope this helps!​ 

Guess you like

Origin blog.csdn.net/2301_76618602/article/details/132739351