A brief introduction to pointers (4) The use of function pointer arrays and qsort

Table of Contents of Series Articles


Preface

Master the use of function pointer arrays and the implementation of qsort function.

1. Purpose of function pointer array

Function: It can make the code more concise and the logic clearer.

Computer implementation:
Simple addition and subtraction operations
Code 1

#include <stdio.h>
int add(int a, int b)//加法
{
    
    
 	return a + b;
}
int sub(int a, int b)//减法
{
    
    
 	return a - b;
}
int main()
{
    
    
 	int x, y;
 	int input = 1;
 	int ret = 0;
 do
 {
    
    
 	printf("*************************\n");
 	printf(" 1:add 			   2:sub \n");
 	printf(" 0:exit 				 \n");
 	printf("*************************\n");
 	printf("请选择:");
 	scanf("%d", &input);
 	switch (input){
    
    
 	case 1:
 		printf("输⼊操作数:");
 		scanf("%d %d", &x, &y);
 		ret = add(x, y);
 		printf("ret = %d\n", ret);
 		break;
 	case 2:
 		printf("输⼊操作数:");
 		scanf("%d %d", &x, &y);
 		ret = sub(x, y);
 		printf("ret = %d\n", ret);
 		break;
 	default:
 		printf("选择错误\n");
 		break;
 	}
 } while (input);
 return 0;
}

Insert image description here
At this time, you can use the function pointer array,
Transformation:
Code 2

#include <stdio.h>
int add(int a, int b)
{
    
    
 	return a + b;
}
int sub(int a, int b)
{
    
    
 	return a - b;
}
void calc(int(*pf)(int, int))
{
    
    
 	int ret = 0;
 	int x, y;
 	printf("输⼊操作数:");
 	scanf("%d %d", &x, &y);
 	ret = pf(x, y);
 	printf("ret = %d\n", ret);
}
int main()
{
    
    
 	int x, y;
 	int input = 1;
 	int ret = 0;
 	int(*p[3])(int x, int y) = {
    
     0, add, sub }; //转移表
 do
 {
    
    
  	printf("*************************\n");
 	printf(" 1:add 			   2:sub \n");
 	printf(" 0:exit 				 \n");
 	printf("*************************\n");
 	printf("请选择:");
 	scanf("%d", &input);
	if ((input <= 4 && input >= 1)){
    
    
 		printf( "输⼊操作数:" );
 		scanf( "%d %d", &x, &y);
 		ret = (*p[input])(x, y);
 		printf( "ret = %d\n", ret);
 	}
 	else if(input == 0)
 	{
    
    
 		printf("退出计算器\n");
 	}
 	else
 	{
    
    
 		printf( "输⼊有误\n" ); 
 	}
  	return 0;
}

Looks like this is very simple, so how is it called?

int(*p[3])(int x, int y) = {
    
     0, add, sub };

As shown in the picture:
Insert image description here

2. Callback function

A 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, the called function is the callback function.
The callback function is not called directly by the implementation of the function, but is called by another party when a specific event or condition occurs, and is used to handle the event or condition. Respond. In the computer implementation code we wrote in Code 1 above, the code in the red box appears repeatedly. Although the logic of performing calculations is different, the input and output operations are redundant. Is there any way? How about simplifying it?
Because of the code in the red box, only the logic of calling the function is different. We can pass the address of the called function in the form of a parameter and use the function pointer to receive it. The function pointed to by the function pointer will be called. What is actually used here is the function of the callback function.

3. qsort function

The qsort function can sort all data types

Necessary parameters for passing parameters:
Insert image description here
So how did she achieve it?
Code 3:

#include <stdio.h>
//qosrt函数的使⽤者得实现⼀个⽐较函数
int int_cmp(const void * p1, const void * p2)
{
    
    
 	return (*( int *)p1 - *(int *) p2);
}
int main()
{
    
    
 	int arr[] = {
    
     1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
 	int i = 0;
 
 	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), 	int_cmp);
 for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)
 {
    
    
 		printf( "%d ", arr[i]);
 }
 		printf("\n");
 return 0;
}

The explanation is as shown in the figure:Insert image description here
The comparison function is received by a function pointer. I will talk about the internal implementation later

3. 1 Use qsort to sort structure data

Can be by name or age
Code 4:

struct Stu //学⽣
{
    
    
 	char name[20];//名字
 	int age;//年龄
 };
//假设按照年龄来⽐较
int cmp_stu_by_age(const void* e1, const void* e2)
{
    
    
 	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//strcmp - 是库函数,是专⻔⽤来⽐较两个字符串的⼤⼩的
//假设按照名字来⽐较
int cmp_stu_by_name(const void* e1, const void* e2)
{
    
    
 	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
//按照年龄来排序
void test2()
{
    
    
 	struct Stu s[] = {
    
     {
    
    "zhangsan", 20}, {
    
    "lisi", 30}, {
    
    "wangwu", 15} };
 	int sz = sizeof(s) / sizeof(s[0]);
 	qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}
//按照名字来排序
void test3()
{
    
    
 	struct Stu s[] = {
    
     {
    
    "zhangsan", 20}, {
    
    "lisi", 30}, {
    
    "wangwu", 15} };
 	int sz = sizeof(s) / sizeof(s[0]);
 	qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
int main()
{
    
    
 	test2();
 	test3();
 return 0;
}

The code explanation is as shown in the figure:
Insert image description here

5…Simulation implementation of qsort function

Use the callback function to simulate the implementation of qsort (using bubbling method).

Supplement: qsort can sort all data types. The code written below is the internal implementation of qsort

Note: This is the first time that the void* pointer is used to explain the role of void*.

#include<stdio.h>
int int_cmp(const void * p1, const void * p2)//比较函数跟qsort函数的比较函数一样
{
    
    
 	return (*( int *)p1 - *(int *) p2);
}
void _swap(void *p1, void * p2, int size)
{
    
    
 	int i = 0;
 	for (i = 0; i< size; i++)//因为不知道数据类型(void)所以两个元素选择一个一个字节交换
 	{
    
    
 		char tmp = *((char *)p1 + i);
 		*(( char *)p1 + i) = *((char *) p2 + i);
 		*(( char *)p2 + i) = tmp;
 	}
}
void bubble(void *base, int count , int size, int(*cmp )(void *, void *))
{
    
    
 	int i = 0;
 	int j = 0;
 for (i = 0; i< count - 1; i++)
  {
    
    
	for (j = 0; j<count-i-1; j++){
    
    //和冒泡相似
 		if (cmp ((char *) base + j*size , (char *)base + (j + 1)*size) > 0)//cmp函数返回值是int,判断>0,如果成立,执行语句
 		{
    
    
 			_swap(( char *)base + j*size, (char *)base + (j + 1)*size, size);//size是宽度,不知道
 		}
	}
  }
 }
int main()
{
    
    
 	int arr[] = {
    
     1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
 	int i = 0;
 	bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);
 	for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)//打印
 	{
    
    
 		printf( "%d ", arr[i]);
 	}
 	printf("\n");
 return 0;
}

Analysis: In the above code comments, there is also an explanation of the if statement code, as shown in the figure:
Insert image description here
Okay, that’s all the content for today! You guys have all seen this, give it a like, thank you, see you next time.

Guess you like

Origin blog.csdn.net/chendemingxxx/article/details/134723307