Detailed explanation of C language—advanced pointers (2)

Table of contents

1. Array of function pointers

Purpose: transfer form

2. Pointer to array of function pointers

3.Callback function

Case:

 qsort function

Sort array:

 Sorting structure:


1. Array of function pointers

An array is a storage space that stores data of the same type.

Then you need to store the address of the function in an array, then this array is called a function pointer array.

How to define the array of function pointers?

int (*pf[10])(int, int);

 The combination of pf and [10] indicates that pf is an array, and the content of the array is a function pointer of type int(*)().

The array size does not need to be written, but an initial value must be assigned.

Purpose: transfer form

In the calculator we can use transfer tables  .

First we write the function that implements the "addition, subtraction, multiplication and division" functions of the 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;
}

 Then write a start menu with prompt function.

void menu()
{
	printf("****************************\n");
	printf("***  1.add        2.sub  ***\n");
	printf("***  3.mul        4.div  ***\n");
	printf("***  0.exit              ***\n");
	printf("****************************\n");
}

To implement a transfer table in a calculator, an array of function pointers is required.

int main()
{
	int input = 0;
	int x = 0,y = 0;
	do {
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		int (*pfArr[])(int, int) = { NULL,Add,Sub,Mul,Div };
		if (input == 0)
			printf("退出计算器\n");
		else if (input >= 1 && input <= 4) {
			printf("请输入两个整数\n");
			scanf("%d %d", &x, &y);
			int ret = pfArr[input](x, y);
			printf("ret = %d\n", ret);
		}
		else
			printf("选择错误,重新选择!\n");
	} while (input);
	return 0;
}

Start executing the program through the do-while statement, and determine whether the program is running based on the value of input.

First enter the value of input, and then create a function pointer array int (*pfArr[ ])(int, int),

And assign it {NULL,Add,Sub,Mul,Div}. The following table of the array assigns NULL to 0 so that the input value starts from 1.

int (*pfArr[ ])(int, int) = { NULL,Add,Sub,Mul,Div };This is the transfer table

Store (transfer) the addition, subtraction, multiplication and division functions to the pfArr[] function pointer array.

Then choose whether to perform calculations and what calculations to perform based on the input value.

If calculation is performed, the two integers involved in the calculation are input, the corresponding function stored in the function pointer array is called through int ret = pfArr[input](x, y), and the input "x" and "y" are transmitted for calculation.

Finally, the value of the calculation result ret is output.

2. Pointer to array of function pointers

A pointer to an array of function pointers is a pointer
The pointer points to an array , and the elements of the array are function pointers. 

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

A callback function is a function called through a function pointer. If you pass the pointer (address) of a function as a parameter to another
Function, when this pointer is used to call the function it points to, we say it is a callback function. The callback function is not defined by the function
is called directly by the implementing party, but is called by another party when a specific event or condition occurs, to carry out the event or condition.
line response.

Case:

Please look at this code:
void calc(int (*pf)(int, int))
{
	int x = 0, 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;
	int x = 0, y = 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;
}

The switch-case statement is used to input different input values ​​​​to perform different operations, and the calculator function is implemented each time through the calc function.

Then create the calc function. The parameter is defined as a function pointer pf. pf has two integer parameters, which are used to receive two integers for calculation. Addition, subtraction, multiplication and division functions of different functions are passed as parameters into the calc function and define ret = pf(x, y) calls the function passed in pf, and then returns the function output result.

When corresponding calculations are required, the required addition, subtraction, multiplication and division functions are passed as parameters to the calc function and stored in the function pointer pf, and pf is called through the custom variable ret to implement the corresponding addition, subtraction, multiplication and division functions passed in. This is the callback function. 

 qsort function

 qsort is a library function, included in the <stdlib.h> header file. The bottom layer uses quick sort to sort data. It can be used directly and can be used to sort any type of data.

//void* 类型指针不能进行解引用操作符,也不能进行+-整数的操作符
//void* 是用来存放任意类型数据的地址
//void*  无具体类型的指针
void qsort(void* base,  //待排序数组的第一个元素
			size_t num, //待排序数组的元素个数
			size_t size,//待排序数组中一个元素的大小
			int (* cmp)(const void* e1,const void* e2))//函数指针指向比较函数
			//e1和e2中存放的是需要比较的两个元素的地址
//排序整型数据,两个整型可以直接使用>比较
//排序结构体,两个结构体数据可能不能直接使用<>比较
//也就是不同类型数据,比较大小,方法有差异

Sort array:

#include <stdio.h>
#include <stdlib.h>
void print_arr(int arr[], int sz)
{
	for (int 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;
}

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);
}

int main()
{
	test1();
	return 0;
}
  1. Define the function print_arr to print the sorting results.
  2. Create a cmp_int comparison function. The input parameter type can be any. Use  const keywords to modify function parameters to indicate that these parameters are read-only and cannot be modified.
  3. Casts  e1 and  e2 to a pointer to an integer ( int*). e1 and  e2 are usually declared as  const void*, this is because  qsort the function requires that the arguments to the comparison function be  const void* of type, so they need to be cast back to integer pointers before comparison.
  4. *(int*)e1 and  *(int*)e2: This part is the dereference operations, they convert the pointer to the integer value pointed to. Because  e1 and  e2 have been cast to integer pointers,  *(int*)e1 and  *(int*)e2 represent two integers respectively.
  • The subtraction operator is used to calculate the difference between two integers.
  • The entire expression calculates the difference between two integers and returns the result.
  • If the result is positive, it means the first integer is greater than the second integer.
  • If the result is negative, it means that the first integer is less than the second integer.
  • If the result is zero, it means the two integers are equal.

 Sorting structure:

After learning qsort, we can also sort various types, such as structure types.

#include <stdio.h>
#include <stdlib.h>
struct Stu
{
	char name[20];
	int age;
};

//结构体输出函数
void print_arrr(struct Stu arr[], int sz)
{
	for (int i = 0; i < sz; i++) {
		printf("%s: %d\n", arr[i].name, arr[i].age);
	}
}

 //按照年龄比较
int cmp_stu_by_age(const void* e1, const void* e2)
{
	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void test2()
{
	struct Stu arr1[] = { {"zhangsan",20},{"lisi",30},{"王五",12} };
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	qsort(arr1, sz, sizeof(arr1[0]), cmp_stu_by_age);
	print_arrr(arr1, sz);
}
 
 //按照名字比较
#include <string.h>
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 arr1[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 12} };
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	qsort(arr1, sz, sizeof(arr1[0]), cmp_stu_by_name);
	print_arrr(arr1, sz);
}
int main()
{
	test2();
	test3();
	return 0;
}

Note: Structure members  name do  age not require dereference operations because they are data stored directly in the structure, not pointers.

Let’s get into C language—advanced pointers (3) ! ! !

Guess you like

Origin blog.csdn.net/m0_73800602/article/details/132765169