Detailed explanation of function pointer and function callback _c language in C language programming

Source: Internet
Author: User
Tags call back define function ming strcmp

function pointers:

is to store the function address of the pointer, is to point to the function of the pointer, that is the value of the pointer store is the function address, we can through the pointer can call the function.

Let's start by defining a simple function:

Define such a function
void Easyfunc ()
{
  printf ("I ' m a Easy function\n");
}
Declares a function
void Easyfunc ();
Call function
Easyfunc ();

Define such a function
void Easyfunc ()
{
  printf ("I ' m a Easy function\n");
}
Declares a function
void Easyfunc ();
Call function
Easyfunc ();

The top three steps are what we have to do to learn the function, and only three steps above we can define a complete function.

How do you define a function pointer? The format of the other types of pointers we defined earlier is the type * pointer name = An address, for example:

int *p = &a;//defines a pointer p that stores a cosmetic address

That is to say, if we want to define what type of pointer we have to know what type, then how is the type of function determined? The type of function is the declaration of a function that removes the function name, such as the type of function above:

void ()

Let's declare a function with parameters and return values:

int add (int a, int b);

The type of function above is still to remove the function name:

int (int a, int b)

Now that we know the type of the function, then the type of the function pointer is to add a * to the back, is that it?

int (int a, int b) *//This is absolutely wrong.

The above definition is wrong, absolutely wrong, many beginners do this, always feel that should be so, in fact, the definition of the type of function pointer is very special, it is like this:

Int (*) (int a, int b); The model here is in the middle, so be sure to enclose it in parentheses

Int (*) (int a, int b);//The model here is in the middle and must be enclosed in parentheses.

We define function pointers simply by adding a pointer name to the *, which is the following:

Int (*p) (int a, int b) = null;//initialized to null

int (*p) (int a, int b) = null;//initialized to null

If we were to assign a value to P, we should define a function with a return value type of int and two parameters int:

int add (int a, int b)
{return
  a + b;
}
p = add;//to function pointer assignment

int add (int a, int b)
{return
  a + b;
}
p = add;//to function pointers

After the above assignment, we can use p to represent the function:

P (5, 6);//equivalent to add (5, 6);
printf ("%d\n", p (5, B));

P (5, 6);//equivalent to add (5, 6);
printf ("%d\n", p (5, b));

The output is: 11

By using the function in the pointer function above, it is not usually the main usage of the function, we use the function pointer to implement the function callback, and use the function as parameter.

Value of function pointer

The function pointer, like a normal pointer, is a memory address, except that this address is the starting address of a function, which prints out the value of a function pointer (func1.c):

#include <stdio.h>

typedef int (*FUNC) (int);

int Double (int a)
{return
  (A + a);
}

int main ()
{
  Func p = Double;
  printf ("%p\n", p);
  return 0;
}

Compile and run the program:

[Lqy@localhost notlong]$ gcc-o2-o func1 func1.c
[lqy@localhost notlong]$./func1
0x80483d0
[ Lqy@localhost notlong]$ 

Then we look at the Double address with the NM tool to see if it's just 0x80483d0:

[Lqy@localhost notlong]$ nm func1 | Sort
08048294 t _init
08048310 t _start
08048340
t __do_global_dtors_aux 080483a0 t Frame_dummy 080483d0 t Double
080483e0 t main
...

Not surprisingly, the starting address of Double is indeed 0x080483d0.

Function callback

The essence of function callback is to make function pointer as function parameter, when function call is passed to function address, that is to name of functions.

When do we use the callback function? Let's give an example, for example, now Xiaoming is not doing his homework now, so he called Xiao Hong to say: I do not have a problem in the homework, can you help me do it? And tell me the answer? Xiao Hong heard that this problem is not immediately can be done, so with Xiaoming said I told you after I finished. This is done to tell Xiaoming is the function of the callback, how to Tell Xiaoming, Xiao Hong must have Xiaoming's contact method, this contact is a callback function. Next we use code to implement:

Xiao Ming needs to leave the contact method for Little Red, but also have to get the answer, so need a parameter to save the answer:

void Contactmethod (int answer)
{
  //output the answer
  to printf ("Answer:%d\n", answer);
}

void Contactmethod (int answer)
{
  //output the answer
  to printf ("Answer:%d\n", answer);
}
Little Red here have to get the contact of Xiaoming, need to use function pointers to store this method:


void tellxiaoming (int xiaohonganswer, void (*p) (int))
{
  p ( xiaohonganswer);
}
When Little red the answer to make out, Xiao Red the answer through Xiaoming left the contact way passed
tellxiaoming (4, contactmethod);

void tellxiaoming (int xiaohonganswer, void (*p) (int))
{
  P (xiaohonganswer);
}
When Little red the answer to make out, Xiao Red the answer through Xiaoming left the contact way passed
tellxiaoming (4, Contactmethod);


One of the callbacks above asks why we can't directly call the Contactmethod function in the Tellxiaoming method? Because if you use a function pointer as a parameter, not only can store Xiaoming's contact method, but also can store the contact way of the small army, so my side of the code will not be modified, you just need to pass the different parameters on the line, so the design code reuse is very high, flexibility is very big.

The whole process of a function callback is this, and here's the main feature is that when we use the callback, generally used in a method to wait for the operation, such as the red above to wait until the answer to do out of the time to notify Xiaoming, as when Xiaoming asked Xiao Red, red directly to give the answer, there is no need for a callback, The order of execution is:

The order of callbacks is:

Above the little red to do is a waiting operation, more time-consuming, xiaoming can not have been holding the phone waiting, so only small red to make, and then call back to tell Xiao Ming answer.

Therefore, the function callback has two main characteristics:

function pointers as arguments, you can pass in different functions, so you can callback different functions
Function callbacks are generally used in cases where a wait or time consuming operation is required, or when a callback is performed after a certain period or event is triggered
We use a function callback to implement a dynamic sort, we now have a student's structure, which contains the name, age, score, we have a method of sorting students, but specifically according to the name of the row? Or the age line? Or a score row? This is not certain, or there will be new requirements, so after the dynamic sorting is written, we simply pass in a different function.

Define student Structure:

Defines a structural body student, containing name,age and score
struct Student {
  char name[255];
  int age;
  float score;
};
The typedef struct student is student
typedef struct Student student;

Enumeration that defines the result of the comparison:

Define comparison results Enumeration
enum Compareresult {
  Student_lager = 1,//1 represents greater than
  Student_same = 0,//0 represents equals
  student_ smaller = -1//-1 represents less than
};
The typedef enum COMPARERESULT is a studentcompareresult
typedef enum COMPARERESULT Studentcompareresult;

Define grades, age, and performance comparison functions:

* * Through grades to compare students/Studentcompareresult Comparebyscore (Student st1, Student st2) {if (St1.score > St2.score) {//if the front
  Students score higher than the back of the students, returned 1 return student_lager;
  else if (St1.score = = St2.score) {//If the previous student score equals the back student score, return 0 returns Student_same;
  else {//If the previous student score is below the student's score behind, return-1 returns Student_smaller; }/* Pass age to compare student */Studentcompareresult Comparebyage (Student st1, Student st2) {if (St1.age > St2.age) {//If the previous study
  The birth age is greater than the rear student age, returns 1 return student_lager;
  else if (st1.age = = st2.age) {//If the preceding student age equals the rear student age, return 0 returns Student_same;
  else {//If the front student is younger than the back student age, return-1 returns Student_smaller; }/* By name to compare student/Studentcompareresult comparebyname (Student st1, Student st2) {if (strcmp (St1.name, St2.name)
  > 0) {//If the name of the preceding student in the dictionary is greater than the sort of the back student name in the dictionary, returns 1 return student_lager;
  else if (strcmp (st1.name, st2.name) = = 0) {//If the preceding student name in the dictionary is sorted equal to the sort of the back student name in the dictionary, returns 0 return student_same;
   else {//If the previous student name in the dictionary sort less than the back student name in the dictionary sort, return-1 return student_smaller;
 }  
}

To define a sort function:


  /* Students are sorted according to different comparisons
  stu1[]: Student array
  count: Number
  of students P: function pointer to pass different comparison modes function
/void Sortstudent (  Student stu[], int count, Studentcompareresult (*p) (Student st1, Student st2))
{for
  (int i = 0; i < count-1; i++) {for
    (int j = 0; J < count-i-1; j +) {
      if (p (stu[j), Stu[j + 1]) > 0) {
        Student = s TU[J];
     STU[J] = stu[j + 1];
       Stu[j + 1] = Tempstu}}}

To define a structure body array:

Definition four student structure body
Student st1 = {"Lingxi", 60.0};
Student st2 = {"Blogs", 70.0};
Student st3 = {"Hello",};
Student St4 = {"World", 40.0};
Defines an array of structures, storing the top four students
Student sts[4] = {st1, st2, ST3, ST4};

An array of outputs sorted before, sorted and sorted:

Output sort the name of the student in the array before
printf ("Before \ n");
for (int i = 0; i < 4; i++) {
  printf ("name =%s\n", sts[i].name);//output name
}
//Sort
sortstudent (STS, 4, CO Mparebyname);
Output sorted after the student name in the array
printf ("After \ n");
for (int i = 0; i < 4; i++) {
  printf ("name =%s\n", sts[i].name);
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.