C language - advanced pointers (2)

Table of contents

7. Array of function pointers

8. Pointer to function pointer array

Nine. Callback function

end


7. Array of function pointers

To put it bluntly, a function pointer array means adding [ ] after the function pointer name, and the two are combined to form an array.

So what is the use of this array of function pointers? Don't worry, let's use a calculator function code to give you some ideas.

This is a simple calculator code that calculates numbers by selecting different functions to enter different functions.

void menu()
{
	printf("***********************\n");
	printf("*****1.add   2.sub*****\n");
	printf("*****3.mul   4.div*****\n");
	printf("*****0.exit       *****\n");
	printf("***********************\n");
}
int Add(int x, int y)
{
	return x + y;
}
int Sub(int x, int y)
{
	return x - y;
}
int Mull(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("请输入两个数字:\n");
			scanf("%d %d", &x, &y);
			ret = Add(x, y);
			printf("%d\n", ret);
			break;
		case 2:
			printf("请输入两个数字:\n");
			scanf("%d %d", &x, &y);
			ret = Sub(x, y);
			printf("%d\n", ret);
			break;
		case 3:
			printf("请输入两个数字:\n");
			scanf("%d %d", &x, &y);
			ret = Mull(x, y);
			printf("%d\n", ret);
			break;

		case 4:
			printf("请输入两个数字:\n");
			scanf("%d %d", &x, &y);
			ret = Div(x, y);
			printf("%d\n", ret);
			break;

		case 0:
			printf("退出程序\n");
			break;

		default :
			printf("输入错误,请重新输入:\n");




		}

		
	} while (input);


	return 0;
	
}

But in this way we will find a problem. When we try to add more functions, the switch will become longer and more complicated.

By analyzing the code, we can know that the functions of each function are actually different, but the formal parameters they use and the function types they represent are the same. 

Next let's modify the code:

First delete the switch part and change it to an array of function pointers.

You can see that the subscripts here do not correspond to the selection of our calculator. At this time, NULL can be used to occupy a position in the array.

Then just use the conditional if statement to implement the function.

8. Pointer to function pointer array

If you are interested, you can use it as an extension to learn more~

A pointer pointing to an array of function pointers is essentially a pointer, so the storage object should be the address of the array of function pointers.

The pointer we need is enclosed by (*p) to ensure that it is a pointer and not an array. Here pfArr is simplified to p for easy identification. Finally, it becomes a pointer to this array. The point is to point to an array, not become an array.

Nine. Callback function

Let's go back to the switch code part to implement the callback function: we can encapsulate a function first, and then call the similar part of the code 4 times.

This is the magic of the callback function. Use a function pointer to accept the required function function. In the calc function, use the pointer that has accepted the address of the function function to enter the actual parameters.

Further understanding of callback functions:

As is the old rule, let’s use simple examples to help everyone understand, and then we’ll learn more about the wonderful uses of qsort. Let’s start with a classic example: bubble sort.

In fact, bubble sorting is very simple. For 10 elements, the element must be exchanged 9 times at worst, and for n elements, it must be exchanged n-1 times. Each time the next element is run through, the contrast will be reduced by one.

In fact, this function is not general enough, it can only sort integers.

Next we will introduce the qsort function, this universal sorting function.

Through this we know that the comparison methods of two data of the same type are different.

Then it can be deduced that the fourth formal parameter of qsort is to provide a comparison method between two data. We can imagine transferring 9 and 8 in the appeal bubble sort to e1 and e2 respectively, and let them compare in cmp. However, you will encounter a problem at this time. *e1 will make an error because the void* type cannot be dereferenced.

The real role of void* is to accept pointers of various types:

Therefore, if you want to implement integer size comparison, you can only force conversion first.

The rule of cmp is that when the element pointed to by p1 > the element pointed by p2, a number greater than 0 is returned, if equal, 0 is returned, and if less than 0, a number less than 0 is returned.

Run the code and the sorting is successful. In fact, the most critical part of qsort is the fourth formal parameter. You must create a comparison method corresponding to the data type before it can be performed. For example, integers can be compared using <>, structures can be compared using string lengths, etc.

 

Let's test structure sorting:

Now comes the most critical part of creating a comparison function.

 

 Try comparing by name again. At this time, the name is a string, and the minus sign cannot be used to express the result. You can use the strcmp function to compare strings. Coincidentally, the return type of strcmpd is consistent with the return rule of cmp.

 

The sorting between strings is compared in dictionary order. For example, abc and aq. The two a's are the same at the beginning, but the subsequent q is larger than b, so abc is ranked in front of aq.

end

The most exciting part of this article is qsort sorting. It is different from our traditional single type of sorting. It is more diverse and gives us more sorting ideas.

Guess you like

Origin blog.csdn.net/fax_player/article/details/132779429