当前位置:网站首页>[advanced pointer (2)] | [function pointer, function pointer array, callback function] key analysis + code explanation
[advanced pointer (2)] | [function pointer, function pointer array, callback function] key analysis + code explanation
2022-07-03 05:38:00 【Sobtemesa】
Laziness is a poor factory .
Catalog
1. Definition form of function pointer :
3. Parse two interesting pieces of code :
2. Purpose of function pointer array
A pointer to an array of function pointers
2.qsort The application of function :
3. Simulation Implementation qsort( Bubble sorting is adopted )
A function pointer
A function always occupies a continuous memory area , The function name can be converted into the first address of the region in the expression , We can put this of the function The first address is assigned to a pointer variable , Make it point to the memory area where the function is located , Then you can find and call this function through the pointer variable , This pointer is A function pointer .
1. Definition form of function pointer :
returnType (*pointerName) (param list);
Return type (* Pointer name )( Function parameter )
eg:void (*p) (int)
notes :() Priority over * , The first bracket cannot be omitted
& Function names and Function name , All function addresses , This is different from arrays .
2. Function call
3. Parse two interesting pieces of code :
1.
(*(void (*)() ) 0)( ) ;
2.
void( *signal ( int , void(*)(int) ) ) (int);
analysis : First , In the definition form of a variable , Let's get rid of its variable name , The rest is its type . for example :
int a; ----- a yes int type
char ch;----ch yes char type
int* b;-----b yes int* type , namely b It's a pointer variable ;
int *arr[10]; -----arr yes int* [10] type , namely arr Is an array of pointers
int (*p)[10];------p yes int (*)[10] type , namely p It's an array pointer
void (*p)();----------p yes void(*)() type , namely p Is a function pointer
1.
2.
Code 2 is too complicated , We can simplify
We said that before ,signal The return type of the function is void(*)(int), This is too long to read , Let's redefine its type ;
You may think it should look like this ,
typedef void(*)(int) pfun_t;
unfortunately , No, oh , The new function type name needs to be followed by the asterisk *, It's like this
typedef void(*pfun_t)(int);
then , This lengthy code can be changed into :
pfun_t signal(int, pfun_t);
Function pointer array
1. Definition form
An array is a storage space for the same type of data , We have learned about pointer arrays :
int *arr[10]; Each element of the array is int*, It's a pointer
If we want to store the addresses of several functions in an array , This array is called the function pointer array . The definition takes the form of :
int (* arr[7]) ( int );
arr The first and [ ] combination , Indicates an array , Array has 7 Elements , Every element is int(*)() That is, the function pointer type .
2. Purpose of function pointer array
What's the use of him ?
Let's use a piece of code to realize the calculator :
#include<stdio.h>
void menu()
{
printf("*********0.exit*************\n");
printf("***1.add*******2.sub********\n");
printf("***3.mul*******4.div********\n");
printf("****************************\n");
printf("****************************\n");
}
int add(int a, int b)
{
int z = a + b;
return z;
}
int sub(int a, int b)
{
int z = a - b;
return z;
}
int mul(int a, int b)
{
int z = a * b;
return z;
}
int div(int a, int b)
{
int z = a / b;
return z;
}
int main()
{
int input = 0;
int x = 0;
int y = 0;
do
{
menu();
printf(" Please select ->");
scanf("%d", &input);
switch (input)
{
case 0:
printf(" sign out ");
break;
case 1:
printf(" Please enter your operand ");
scanf("%d%d", &x, &y);
printf("%d\n",add(x,y));
break;
case 2:
printf(" Please enter your operand ");
scanf("%d%d", &x, &y);
printf("%d\n", sub(x, y));
break;
case 3:
printf(" Please enter your operand ");
scanf("%d%d", &x, &y);
printf("%d\n", mul(x, y));
break;
case 4:
printf(" Please enter your operand ");
scanf("%d%d", &x, &y);
printf("%d\n", div(x, y));
break;
default:
printf(" Input error ");
}
} while (input);
return 0;
}
Using callback functions ( I'll talk about it later ), Do some optimization
void menu()
{
printf("*********************************\n");
printf("***1.add********2.sub************\n");
printf("***3.mul********4.div************\n");
printf("*********0.exit******************\n");
printf("*********************************\n");
printf("*********************************\n");
}
int add(int x, int y)
{
int z = 0;
return z = x + y;
}
int sub(int x, int y)
{
int z = 0;
return z = x - y;
}
int mul(int x, int y)
{
int z = 0;
return z = x * y;
}
int div(int x, int y)
{
int z = 0;
return z = x / y;
}
void caluc(int(*p)(int,int))
{
int x = 0;
int y = 0;
printf(" Please enter your number ");
scanf("%d%d", &x, &y);
printf("%d\n", p(x, y));
}
int main()
{
int input = 0;
do
{
menu();
printf(" Please select :");
scanf("%d", &input);
switch (input)
{
case 0:printf(" sign out \n");
break;
case 1:
caluc(add);
break;
case 2:
caluc(sub);
break;
case 3:
caluc(mul);
break;
case 4:
caluc(div);
break;
default:
printf(" Input error \n");
break;
}
} while (input);
return 0;
}
We can also use function pointer array to realize :
void menu()
{
printf("*********0.exit*************\n");
printf("***1.add*******2.sub********\n");
printf("***3.mul*******4.div********\n");
printf("****************************\n");
printf("****************************\n");
}
int add(int a, int b)
{
int z = a + b;
return z;
}
int sub(int a, int b)
{
int z = a - b;
return z;
}
int mul(int a, int b)
{
int z = a * b;
return z;
}
int div(int a, int b)
{
int z = a / b;
return z;
}
int main()
{
int input = 0;
int x = 0;
int y = 0;
int(*parr[5])(int, int) = {0,add,sub,mul,div};
do
{
menu();
printf(" Please select ->");
scanf("%d", &input);
if (input >= 1 && input <= 4)
{
printf(" Please enter the operands :");
scanf("%d%d", &x, &y);
printf("%d\n", parr[input](x, y));
}
else if (0 == input)
{
printf(" sign out \n");
}
else
{
printf(" Wrong entry \n");
}
} while (input);
return 0;
}
Purpose of function pointer array : Transfer table .
A pointer to an array of function pointers
The pointer to the array of function pointers is a The pointer , The pointer points to a Array , The elements of the array are A function pointer . How is that defined ?
void(*p)(int ,int);----------- This is a function pointer
void(*parr[4])(int ,int);--------- This is an array of function pointers ;
void(*(*pparr)[4])(int ,int);--------- This is a Pointer to function array Of The pointer ;
Callback function
The callback function is a pass Call through function pointer Function of , If you put The address of the function is used as a parameter Pass it to another function , When this pointer Used to call the function it points to when , Let's just say this is Callback function .
The most famous callback function calls are C/C++ Standard library stdlib.h/cstdlib Quick sort function in qsort And binary search function bsearch The one that will be asked for in strcmp Similar parameters , The comparison method used to set the data .
1.qsort function
First , Let's get to know qsort function :
qsort yes qsort function C Sorting function of language compiler function library .
Function declaration : void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));
base: The address of the first element of the array to be sorted
num: Number of array elements
size: The size of each element of the array , In bytes
compar: A function pointer , Point to a function that compares two elements , This function is implemented by the user himself
compar Parameters
int compar(const void* p1,const void*p2)
Compare The return value of the function
describe
< 0
p1 Will be ranked p2 front
0
p1 be equal to p2
> 0
p1 Will be ranked p2 Back
Add : About void:
1.void* The type pointer can accept any type of address
2.void* Type pointers cannot be dereferenced
3.void* Type pointers cannot be used +- Plus or minus integer operation
2.qsort The application of function :
1. Sort floating-point data
int float_cmp(const void*p1, const void* p2)
{
return( int )(*(float*)p1 - *(float*)p2);
}
int main()
{
float arr[] = { 9.0, 8.0, 7.0, 6.0, 5.0, 4.0 };
int sz =sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz,sizeof(float), float_cmp);
for (int i = 0; i < sz; i++)
{
printf("%lf ", arr[i]);
}
return 0;
}
2, Sort integers
int int_cmp(const void*p1, const void*p2)
{
return (*(int*)p1 - *(int*)p2);
}
int main()
{
int i = 0;
int arr[] = { 9, 8, 7, 6, 5, 4, 3, 2, 10 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr,sz,sizeof(int),int_cmp);
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
3. Sort structures
struct stu
{
char name[20];
int age;
};
int struct_name_cmp(const void*p1, const void*p2)
{
return strcmp( ( (struct stu*)p1 )->name,( (struct stu* )p2) ->name);
}
int struct_age_cmp(const void*p1, const void*p2)
{
return ((struct stu*)p1)->age - ((struct stu*)p2)->age;
}
int main()
{
struct stu class1[3] = { { "zhangsan", 20 }, { "lisi", 33 }, { "wangwu", 67 } };
int sz = sizeof(class1) / sizeof(class1[0]);
qsort(class1, sz, sizeof(class1[0]), struct_name_cmp);
qsort(class1, sz, sizeof(class1[0]), struct_age_cmp);
return 0;
}
1). The original sequence
2) Sort by first name
3) Sort by age
summary ;
We put cmp The address of this callback function is passed to qsort function , It realizes the comparison of the size of two elements in the sequence sorting . Use qsort Function to sort , It has a wider scope of application than the bubble sorting we used before . We used to sort only integer arrays , Have limitations .
Bubble sort ( Only integer types can be sorted )
void bubble_sort(int arr[], int sz)
{
int i = 0;// Number of trips
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
int tmp = 0;
if (arr[j]>arr[j + 1])
{
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
3. Simulation Implementation qsort( Bubble sorting is adopted )
int int_cmp(const void*p1, const void*p2)
{
return (*(int*)p1 - *(int*)p2);
}
int float_cmp(const void*p1, const void* p2)
{
return( int )(*(float*)p1 - *(float*)p2);
}
struct stu
{
char name[20];
int age;
};
int struct_name_cmp(const void*p1, const void*p2)
{
return strcmp( ( (struct stu*)p1 )->name,( (struct stu* )p2) ->name);
}
int struct_age_cmp(const void*p1, const void*p2)
{
return ((struct stu*)p1)->age - ((struct stu*)p2)->age;
}
swap(char* p1,char* p2,int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *p1;
*p1 = *p2;
*p2 = tmp;
p1++;
p2++;
}
}
void bubble(void* base, int count,int width, void*(*cmp)(void*,void*))
{
int i = 0;
// Number of trips
for (i = 0; i < count - 1; i++)
{
int j = 0;
// The logarithm of each trip to be compared
for (j = 0; j < count - 1 - i; j++)
{
// Call function , Compare the size of two elements
if (cmp( (char*)base+j*width, (char*)base + (j+1)*width )>0)
{
// Exchange two elements
swap((char*)base + j*width, (char*)base + (j + 1)*width,width );
}
}
}
}
void test2()
{
struct stu s[3] = { {"zhangsan",20},{"lisi",19},{"wangwu",77} };
int sz = sizeof(s) / sizeof(s[0]);
bubble(s, sz, sizeof(s[0]), struct_name_cmp);
}
void test1()
{
int arr[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble(arr, sz, sizeof(int), int_cmp);
for (int i = 0; i < sz; i++)
{
printf("%d ",arr[i]);
}
}
int main()
{
//test1();
test2();
return 0;
}
边栏推荐
- Skip table: principle introduction, advantages and disadvantages of skiplist
- 3dslam with 16 line lidar and octomap
- 今天很多 CTO 都是被幹掉的,因為他沒有成就業務
- 【无标题】
- Transferring images using flask
- Introduction to redis using Lua script
- 在PyCharm中配置使用Anaconda环境
- Redis encountered noauth authentication required
- Introduction to redis and explanation of data types
- Azure file synchronization of altaro: the end of traditional file servers?
猜你喜欢
"C and pointer" - Chapter 13 function pointer 1: callback function 2 (combined with template to simplify code)
中职网络子网划分例题解析
Skip table: principle introduction, advantages and disadvantages of skiplist
一起上水硕系列】Day 9
Communication - how to be a good listener?
6.23星期四库作业
Deep embedding and alignment of Google | protein sequences
How do I migrate my altaro VM backup configuration to another machine?
谷歌 | 蛋白序列的深度嵌入和比对
Redis cannot connect remotely.
随机推荐
"250000 a year is just the price of cabbage" has become a thing of the past. The annual salary of AI posts has decreased by 8.9%, and the latest salary report has been released
配置xml文件的dtd
Why is go language particularly popular in China
酒店公共广播背景音乐-基于互联网+的酒店IP网络广播系统设计
求质数的方法
联想R7000显卡的拆卸与安装
Configure and use Anaconda environment in pycharm
2022.DAY592
Source insight automatic installation and licensing
AtCoder Beginner Contest 258(A-D)
Shanghai daoning, together with American /n software, will provide you with more powerful Internet enterprise communication and security component services
"C and pointer" - Chapter 13 advanced pointer int * (* (* (*f) () [6]) ()
[practical project] autonomous web server
The request database reported an error: "could not extract resultset; SQL [n/a]; needed exception is org.hibernate.exception.sqlgram"
Congratulations to musk and NADELLA on their election as academicians of the American Academy of engineering, and Zhang Hongjiang and Fang daining on their election as foreign academicians
Explanation of variables, code blocks, constructors, static variables and initialization execution sequence of static code blocks of Ali interview questions
Apache+PHP+MySQL环境搭建超详细!!!
Go practice -- factory mode of design patterns in golang (simple factory, factory method, abstract factory)
Redis encountered noauth authentication required
穀歌 | 蛋白序列的深度嵌入和比對