当前位置:网站首页>[advanced C language] advanced pointer [Part 2]
[advanced C language] advanced pointer [Part 2]
2022-06-10 19:35:00 【You and I are all mortals】
author : You and I are all mortals
Blog home page : You and I are all mortal blogs
Aphorisms : Time will not stay for anyone , And things and people , It's changing all the time . Every one of us , Also keep moving forward !
If you think the blogger's article is good , I hope you'll make it three times in a row ( Focus on , give the thumbs-up , Comment on ), Give me more support !!
series :

List of articles
Catalog
A pointer to an array of function pointers
Preface
This chapter not only follows up on the previous chapter, but also explains the new knowledge , About function pointers , Function pointer array , Pointers to function pointer arrays and callback functions are troublesome knowledge points at first glance , Some relatively high knowledge points , I hope you can understand and learn
Tips : The following is the main body of this article , The following cases can be used for reference
A function pointer
The previous array pointer refers to the array pointer
A function pointer is a pointer to a function
So we know that The array pointer is the address of the array , that A function is simply to take the address of the function ?
So let's explore function pointers :
#include<stdio.h>
int add(int x, int y)
{
return x + y;
}
int main()
{
int arr[5] = { 0 };
//& Array name -- The address of the extracted array
int(*p)[5] = &arr; // Array pointer
//& Function name - What you get is the address of the function ?
printf("%p\n", &add);
// Function name , It is the address of the first element of the function , How can a function have a first element ?
printf("%p\n", add);
// For functions ,& Function name and function name are the address of the function
// If you want to get the address of the function , How to store it ?
int (*pf)(int, int) = &add;
return 0;
}First of all, pay attention to , Function pointers are actually very similar to array pointers ,& Function name and function name are the address of the function , If you want to get the address of the function , First of all, it is a pointer (*pf) The parameter type in the function is (int,int) The return value is int, This constitutes a function pointer , It points to a function
We use pointers so that we can use them one day , that How function pointers are used ?
int (*pf)(int, int) = &add;
int ret = (*pf)(2, 3);
printf("%d", ret);
return 0;Actually (*pf) Inside * There is no point here , Think about it , since add It can be an address ,&add It's also the address , Then put the add Directly assign to pf It's fine too , Our usual call function is add(2,3), So directly pf(2,3) It's the same thing
So how to use function pointers ?
int add(int x, int y)
{
return x + y;
}
void calc(int(*pf)(int, int))
{
int a = 3;
int b = 5;
int ret = pf(a, b);
printf("%d\n", ret);
}
int main()
{
calc(add);
return 0;
}It seems like a lot of trouble , Call the function directly , Why use it like this ? take it easy , The following will explain an example according to other knowledge points , Let us understand the application scenarios of function pointers
Next, let's look at two interesting and numbing pieces of code :
int main()
{
(*(void (*)())0)();
void (*signal(int, void(*)(int)))(int);
return 0;
}About the drawing and analysis of these two pieces of code :


These two pieces of code adopt c Pitfalls and pitfalls , It is quite difficult to read , If you don't learn this knowledge , So this kind of code certainly doesn't know how to start
Next, let's implement a function pointer , It is convenient for everyone to understand the function pointer
Let's do a simple calculator , The common version is like this :
// The purpose of the function pointer
// Write a calculator
// Add , Subtraction , Multiplication , division
void memu()
{
printf("****************************\n");
printf("** 1 add 2 sub *****\n");
printf("*** 3 mul 4 div *****\n");
printf("**** 0 exit ******\n");
}
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 input = 0;
int x = 0;
int y = 0;
int ret = 0;
do
{
memu();
printf(" Please select :");
scanf("%d", &input);
switch (input)
{
case 1:
printf(" Please enter two actual numbers :");
scanf("%d %d", &x, &y);
ret = add(x, y);
printf("%d\n", ret);
break;
case 2:
printf(" Please enter two actual numbers :");
scanf("%d %d", &x, &y);
ret = sub(x, y);
printf("%d\n", ret);
break;
case 3:
printf(" Please enter two actual numbers :");
scanf("%d %d", &x, &y);
ret = mul(x, y);
printf("%d\n", ret);
break;
case 4:
printf(" Please enter two actual numbers :");
scanf("%d %d", &x, &y);
ret = div(x, y);
printf("%d\n", ret);
break;
case 0:
printf(" Exit calculator \n");
break;
default:
printf(" Wrong choice \n");
break;
}
} while (input);
return 0;
}We found that case1,2,3,4 There is too much code duplication between , Can we directly encapsulate a function , But how to achieve it ?
We make improvements as follows :( Part of the code , Because it's written too much )
We can see below , Function pointer is used , To put all that duplicate code in , The name of every addition, subtraction, multiplication and division function is the address , Then use the function pointer to receive , Call this function internally , This is the callback function , This is not supported without knowing the concept of function pointer
So the function pointer is not a decoration , It is a place that is temporarily unavailable , In fact, it is a clever way
// The purpose of the function pointer
// Write a calculator
// Add , Subtraction , Multiplication , division
// A calculation function encapsulated
void calc(int (*pf)(int,int)) // A function pointer
{
int x = 0;
int y = 0;
int ret = 0;
printf(" Please enter two actual numbers :");
scanf("%d %d", &x, &y);
ret = pf(x, y);
printf("%d\n", ret);
}
int main()
{
int input = 0;
do
{
memu();
printf(" Please select :");
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(" Exit calculator \n");
break;
default:
printf(" Wrong choice \n");
break;
}
} while (input);
return 0;
}Function pointer array
An array is a storage space for the same type of data , We have learned about multiple arrays , such as :
int* arr【5】
char* arr【6】
int arr【4】
So a function pointer is a pointer , Put functions and pointers into arrays , It is actually an array of function pointers
The following code explains the 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 (*pf)(int, int) = add;//pf It's a function pointer
// imitation
int (*arr[4])(int, int) = { add,sub,mul,div };
}So how do we understand ? Drawing comprehension :

How to use it ? We can use the traversal method :
int main()
{
int (*pf)(int, int) = add;//pf It's a function pointer
// imitation
int (*arr[4])(int, int) = { add,sub,mul,div };
int i = 0;
for (i = 0; i < 4; i++)
{
int ret = arr[i](8, 4);
printf("%d\n", ret);
}
}You may have some doubts here , What's the use ? Don't worry , Let's look at a set of code applications , Or the calculator above , So let's revise that :
// The purpose of the function pointer
// Write a calculator
// Add , Subtraction , Multiplication , division
// Transfer table
void memu()
{
printf("****************************\n");
printf("** 1 add 2 sub *****\n");
printf("*** 3 mul 4 div *****\n");
printf("**** 0 exit ******\n");
}
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 input = 0;
int x = 0;
int y = 0;
int ret = 0;
// An array of function pointers
int(*pfarr[5])(int, int) = { 0,add,sub,mul,div };
do
{
memu();
printf(" Please select :");
scanf("%d", &input);
pfarr[input];// Get the element with subscript number according to the entered number
if (input == 0)
{
printf(" Exit calculator \n");
}
else if (input >= 1 && input <= 4)
{
printf(" Please enter two actual numbers :");
scanf("%d %d", &x, &y);
ret = pfarr[input](x, y);
printf("%d\n", ret);
}
else
{
printf(" Wrong choice \n");
}
} while (input);
return 0;
}In the code above , We used an array of function pointers , Make the code very concise , Even if our calculator wants to go into some functions , Add some features , It also becomes very simple
A pointer to an array of function pointers
The pointer to the array of function pointers is a pointer
The pointer points to an array , The elements of the array are function pointers
How to define ? As shown below :( Understanding can , It doesn't go deep here )
#include<stdio.h>
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;
}
#include<stdio.h>
int main()
{
// Function pointer array
int (*pfarr[])(int, int) = { 0,add,sub,mul,div };
// A pointer to an array of function pointers
int (*(*ppfarr)[])(int,int) = &pfarr;
return 0;
}Callback function
A callback function is a function called through a function pointer . If you put a pointer to a function ( Address ) Pass as argument to another function , When this pointer is used to call the function it points to , Let's just say this is a callback function . The callback function is not called directly by the function's implementer , It's called by another party when a particular event or condition occurs , Used to respond to the event or condition .I know it seems hard to understand , Never mind , Let's use an example to explainFirst of all, we have been exposed to bubble sorting before , Know that bubbling sort can only run in shaping , Can only be sorted for integer , Let's sort and library functions according to bubbles qsort To explain :
#include<stdio.h>
void bubble_sort(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int flag = 1;// Suppose the array is ordered
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
flag = 0;
}
}
if (flag == 1)
{
break;
}
}
}
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
// Generate the array in ascending order
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;
}
Next, let's show qsort Use of functions ( The second version ):


( Use qsort Implement sort integer )( Equivalent to callback function )
// Compare two integer elements
//e1 Point to another integer
//e2 Point to another integer
#include<stdio.h>
#include<string.h>
int cmp_int(const void* e1, const void* e2)//void* Is a pointer without a specific type , Can accept any type of address
// Therefore, you cannot dereference the operation , Also can not +- Integers
{
return (*(int*)e1) - (*(int*)e2);
}
void test1()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
// Generate the array in ascending order
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
struct stu
{
char name[20];
int age;
};
int cmp_stu(const void* e1, const void* e2)
{
return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name);
}
void test2()
{
// Test use qsort To sort structural data
struct stu s[] = { {"zhangsan",15},{"lisi",59},{"liwa",44} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu);
// Debug view memory
}
int main()
{
test1();
test2();
return 0;
}
Next, transform the first bubble sort ( simulation qsort function )

#include<stdio.h>
void swap(char* buf1, char* buf2, int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
int cmp_int(const void* e1, const void* e2)
{
return (*(int*)e1) - (*(int*)e2);
}
void bubblu_sort(void* base, int sz, int width, int(*cmp)(const void* e1, const void* e2))
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
int flag = 1;
for (j = 0; j < sz - 1 - i; j++)
{
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
{
// In exchange for
swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
flag = 0;
}
}
if (flag == 1)
{
break;
}
}
}
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
// Generate the array in ascending order
int sz = sizeof(arr) / sizeof(arr[0]);
bubblu_sort(arr, sz, sizeof(arr[0]), cmp_int);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}Entrance to exercises
After reading these specific operations, it is not allowed , You can click on the top to practice some exercises , You can also have a casual look C Some language exercises , Practice multiple-choice questions and programming questions , Let your knowledge be consolidated , Click directly into the title to go directly to , In addition, if you want to get the qualification of internal promotion of large factories, you can also go and have a look :
It is highly recommended that you practice the exercises here , Friendly to novices , The topics are from the simplest aspects , You can choose a series of difficulties, such as simple introduction and medium difficulty , I practiced for a long time , Let's go on the journey of question brushing :


summary
This chapter not only follows up on the previous chapter, but also explains the new knowledge , About function pointers , Function pointer array , Pointers to function pointer arrays and callback functions are troublesome knowledge points at first glance , Some higher knowledge points give different examples to let you know the application of these knowledge , It also explains what the transfer table is and the library functions qsort Simulation Implementation of , Step by step , If you think the blogger's explanation is good , I hope you can support me more , Thank you for watching
边栏推荐
- 写作技术文章是留给自己未来的财富
- 超级简单的课程设计ssm学生管理系统(含源码简单添加、删除、修改、查询操作)
- Monotonic stack structure
- 【C语言】还搞不明白结构体吗?不妨来看看这篇文章,带你初步了解结构体
- MATLAB 根据任意角度、取样点数(分辨率)、位置、大小画椭圆代码
- Musk says he doesn't like being a CEO, but rather wants to do technology and design; Wu Enda's "machine learning" course is about to close registration | geek headlines
- 【web】个人主页web大作业「课表」「相册」「留言板」
- Beijing Metro ticketing system
- [Agency] 10 minutes to master the essential difference between forward agency and reverse agency
- 【C语言进阶】数据的存储【下篇】【万字总结】
猜你喜欢

Sliding window maximum value problem

Libcurl 7.61.0 vs2013 compilation tutorial

c(指针-02)

Design and development of hospital reservation registration platform based on JSP Zip (thesis + project source code)

WordPress 6.0 "Arturo Arturo" release

MySQL (17 trigger)
![[Agency] 10 minutes to master the essential difference between forward agency and reverse agency](/img/67/5f30f36aa60cf605cbc32399a9d9a0.png)
[Agency] 10 minutes to master the essential difference between forward agency and reverse agency

618大促将至,用AI挖掘差评,零代码实现亿级评论观点情感分析

基于SSM流量计量云系统的设计与实现.rar(论文+项目源码)

Ranked first in China's SDN (software) market share for six consecutive years
随机推荐
Monotonic stack structure
APICloud可视化开发丨一键生成专业级源码
云图说|每个成功的业务系统都离不开APIG的保驾护航
Writing technical articles is a fortune for the future
【数据库语言SPL】写着简单跑得又快的数据库语言 SPL
Cet article vous donne un aperçu de la tâche future de j.u.c, du cadre Fork / join et de la file d'attente de blocage
Computer: successfully teach you how to use one trick to retrieve the previous password (the password once saved but currently displayed as ******)
Design and reality of JSP project laboratory management system based on SSM doc
SPSS introductory notes
马斯克称自己不喜欢做CEO,更想做技术和设计;吴恩达的《机器学习》课程即将关闭注册|极客头条
【C语言进阶】数据的存储【下篇】【万字总结】
WordPress 6.0 "Arturo Arturo" release
专项测试之「 性能测试」总结
Debugging skills
Google Earth engine (GEE) -- Copernicus atmosphere monitoring (CAMs) global aerosol AOI near real-time observation data set
Jsp基于ssm项目实验室管理系统设计与现实.doc
Nodejs basic architecture analysis parsing engine directory plug-in installation core module
Beijing Metro ticketing system
写作技术文章是留给自己未来的财富
数据库防火墙的性能和高可用性分析