【Advanced Pointers (2)】——Function pointers and arrays of function pointers


foreword

Following the previous chapter [Advanced pointer (1)], continue to improve the content of the second chapter


1. Function pointer

Meaning: pointer to function

1.1 How to write function pointers

#include<stdio.h>
int Add(int x, int y)
{
    
    
	return x + y;
}
int main()
{
    
    
	int arr[10] = {
    
     0 };
	printf("%p\n", Add);
	//函数名是函数的地址

	printf("%p\n", &Add);
	//&函数名也是函数的地址

	int(*pf)(int,int) = &Add;//函数指针
	return 0;
}

Idea: Save the function address and store it in the variable pf, which is used to store the function address, so the pf type is a function pointer.
Function pointer writing : remove the pointer variable pf, and the rest is actually the function pointer type int(*)(int,int)The left is the return type, the right is the parameter type
It is very similar to an array pointer, int( ptr)[5]=&arr, remove the pointer variable ptr, and the rest is the array pointer type int( )[5]

1.2 Usage of function pointer

The function can be accessed indirectly through the pointer, calling this function

int Add(int x, int y)
{
    
    
	return x + y;
}
int main()
{
    
    
	int (*pf)(int, int) = &Add;
	int r = Add(3, 5);
	printf("%d\n", r);

	int m = pf(4, 5);
	printf("%d\n", m);
	return 0;
}

1.3 Exercises

int main()
{
    
    
	(*(void(*)()) 0)();
}

Interpreting this code means:
void( * )() is a function pointer type
( void( * )() ) casts 0 to a function pointer type
* (void( * )() ) is an address dereference
* (void( * )() ) () The parenthesis at the end is to call this function.
In fact, it is
1. Convert 0 to the address of void(*)() function pointer type
2. Call the function at address 0



int main()
{
    
    
	void ( * signal(int, void(*)(int) ) ) (int);

	return 0;
}

Interpreting this code means:

  • signal is a function declaration
  • signal(int, void( * )(int) ) description: the signal function has two parameters, the type of the first parameter is int, and the type of the other parameter is void( * )(int) function pointer type, the function pointer The function pointed to has an int type and the return type is void
  • The return type of the signal function is also void ( * ) (int) function pointer type, the function pointed to by the function pointer has an int type, and the return type is void

1.4 typedef simplifies code

This code is too complicated and not very interpretable, you can use typedef to simplify it

For example

typedef unsigned int uint;

Rename unsigned int to uint

typedef int * ptr;

Rename the pointer to ptr, int* p1;which is equivalent toptr p2;

typedef void(*ptr_t)(int);
ptr_t signal(int, ptr_t);

NoticeThe pointer function is renamed in (*), such as renaming void(*)(int) to ptr_t, written as void(*ptr_t)(int). The return type of the signal function is also a void( * )(int) function pointer type, so the final abbreviation becomesptr_t signal(int, ptr_t);

2. Array of function pointers

Each element of the array is a function pointer type

analogy

  • int * arr[5]; Array of integer pointers
  • char * arr2[5]; array of character pointers

2.1 How to write function pointer array

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(*pf1)(int,int)= Add;
	int(*pf2)(int,int) = Sub;
	int(*pf3)(int,int) = Mul;
	int(*pf4)(int,int) = Div;

	return 0;
}

The types of function pointers storing the four functions are all the same, and it is easier to use an array of function pointers
. The writing method is as follows:

int main()
{
    
    
	int(*pfarr[4])(int, int) = {
    
     Add,Sub,Mul,Div };

	return 0;
}

2.2 The usefulness of function pointer array

Write a calculator with addition, subtraction, multiplication and division functions. The general writing method is as follows:

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("***************************\n");
	printf("*****  1.add  2.sub  ******\n");
	printf("*****  3.mul  4.div  ******\n");
	printf("*****  0.exit        ******\n");
	printf("***************************\n");
}
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("请输入两个操作数:");
			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;
		case 3:
			printf("请输入两个操作数:");
			scanf("%d %d", &x, &y);
			ret = Mul(x, y);
			printf("ret = %d\n", ret);
			break;
		case 4:
			printf("请输入两个操作数:");
			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;
}

There are a lot of repetitive codes in the mani function, which is too redundant. If you want to add more functions, you need to write more case statements, which is a lot of work and troublesome.
Using an array of function pointers will greatly improve efficiency

Implemented as an array of function pointers

Idea: The use of the function pointer array - also called the transfer table, which means that the subscript of the function corresponds to a number, find the address of a certain function through the subscript, and then call a certain function.

When using a calculator, there are usually three situations. The first one does not want to use it and wants to quit the calculator. The second one chooses the correct number (subscript of the function) to realize the calculation; the third one chooses a value greater than If the number of the subscript of the function is selected, it needs to be re-selected.

For the three cases, it is obvious that the if, else if, else statement is the most suitable, because the subscript of the array starts from 0, so you can let NULL occupy the subscript of 0, let the function start from subscript 1, it will be more Easy to choose.

	int (* pfArr[5])(int, int) = {
    
    NULL, Add, Sub, Mul, Div};
	//                            0     1    2    3    4

First select a number, if the number is greater than 0 and less than the subscript number, enter the loop

if (input >= 1 && input <= 4)

Enter two more numbers, calculate and print.

            printf("请输入两个操作数:");
			scanf("%d %d", &x, &y);
			ret = pfArr[input](x, y);
			printf("ret = %d\n", ret);

If the selected number is 0, exit the calculator;

else if(input == 0)
		{
    
    
			printf("退出计算器\n");
		}

If the selected number is greater than the subscript number, the selection is wrong and re-select.

else
		{
    
    
			printf("选择错误,重新选择\n");
		}

If you want to choose multiple calculations, put the if, else if, and else statements in the dowhile() loop, and the whole process can be looped.

The specific code is as follows:

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("***************************\n");
	printf("*****  1.add  2.sub  ******\n");
	printf("*****  3.mul  4.div  ******\n");
	printf("*****  0.exit        ******\n");
	printf("***************************\n");
}
int main()
{
    
    
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	
	int (* pfArr[5])(int, int) = {
    
    NULL, Add, Sub, Mul, Div};
	//                            0     1    2    3    4
	do
	{
    
    
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		if (input >= 1 && input <= 4)
		{
    
    
			printf("请输入两个操作数:");
			scanf("%d %d", &x, &y);
			ret = pfArr[input](x, y);
			printf("ret = %d\n", ret);
		}
		else if(input == 0)
		{
    
    
			printf("退出计算器\n");
		}
		else
		{
    
    
			printf("选择错误,重新选择\n");
		}
	} while (input);

	return 0;
}

Summarize

This chapter explains function pointers and function pointer arrays in detail. If it is helpful to you, you might as well give it a follow!

Guess you like

Origin blog.csdn.net/2301_76496134/article/details/131775396