Function pointer and pointer function learning summary

  • 2020-04-02 01:14:00
  • OfStack

A function pointer is a pointer to a function. A pointer function is a function whose return value is a pointer. Can you elaborate on that?

(1) the float (def) * * [10]     What is def?
(2) double * (* gh) [10]     What is gh?
(3) double (* f [10]) ()     What is f?
(4) int * ((* b) [10])       What is b? So the old feeling is a bit messy, what trick can remember and understand clearly a bit?

= = = = = = = = = = = = = = = = = = = = = =
Answer:
   
(1) def is a pointer to an object that is also a pointer to an array of 10 floats.

(2) gh is a pointer to an array of 10 elements, and the element of the array is a pointer of double* type.

(3) f is an array of 10 elements, each of which is a pointer to a function with no arguments and a return value of double.

(4) b is a pointer to an array of 10 elements. The array element is an int* pointer.

Here's the trick:
If we encounter a complex type declaration, how do we parse it? Such as:
Char (* a [3]) (int);
What is a being declared for? A pointer? An array? Function?

For analysis, start at the nearest (by operator priority) a. We see that the nearest symbol for a is [] -- note: * has a lower priority than []. Since a has [], then a is an array, and it's a three-element array.

So what is the type of each element of this array? Although array a contains only three elements: a[0], a[1], and a[2], a[3] has actually crossed the line. However, when analyzing the types of elements in array a, we need the formal element a[3]. If you know the type of a[3], you know the type of the element of a. What type is a[3]? Is a pointer because it is preceded by *. Thus, the elements of array a are Pointers.

Pointers are not enough. For a pointer, you must say what type it is pointing to. What it points to depends on what *a[3] is (a[3] is the pointer, and of course it points to *a[3]). Continuing by priority, we see that *a[3] is followed by parentheses, so we can be sure that *a[3] is a function. The elements of array a are Pointers to the function.

What kind of function is that? This is obviously a function of type int and return value char.
This completes the parsing.
According to the above method, again complex can also be resolved step by step.

Just as kung fu is practiced not to hit but to defend oneself, so we know that the above methods are used to read complex statements written by others, not to construct such complex things ourselves in practice. When a complex declaration is needed, a typedef can be used instead. For example, the above sentence can be changed into two sentences:
FUN_PTR typedef char (*) (int);
FUN_PTR a, [3].
That's a lot clearer.
In addition, the above analysis method also makes us more clear about the nature of something. For example, an n-dimensional array is essentially a one-dimensional array. Here's a specific example:
Int a [3] [5].
This statement declares a one-dimensional array of three elements, each of which is an array of five ints. A is a one-dimensional array of five elements, each of which is an array of three ints. Why is that? Or by the way above analysis, here from the omitted.

Some books or websites offer a "look right, look left" method that is not universal, such as it is not suitable for analyzing the nature of multidimensional arrays.

  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 
One, pointer function
When a function declares its return value to be a pointer, it returns an address to the calling function for use in an expression that requires a pointer or address.
Format:
Type specifier * function name (parameter)
Of course, since you're returning an address, the type descriptor is usually an int.
For example: int *GetDate();
          Int * aaa (int, int);
The array_address () function returns an address value, often used on the address of an element in the returned array.


        int * GetDate(int wk,int dy);
        main()
        {
            int wk,dy;
            do
            {
                printf(Enter week(1-5)day(1-7)/n);
                scanf(%d%d,&wk,&dy);
            }
            while(wk<1||wk>5||dy<1||dy>7);
            printf(%d/n,*GetDate(wk,dy));
        }
        int * GetDate(int wk,int dy)
        {
            static int calendar[5][7]=
            {
               {1,2,3,4,5,6,7},
               {8,9,10,11,12,13,14},
               {15,16,17,18,19,20,21},
               {22,23,24,25,26,27,28},
               {29,30,31,-1}
            };
            return &calendar[wk-1][dy-1];
        }
             
The subfunction returns the address of an element in the array. The output is the value in this address.

Function pointer
The pointer to the function contains the address of the function and can be used to call the function. The format of the declaration is as follows:
Type specifier (* function name)(parameter)
You can't call this a function name, you can call this a pointer variable name. This special pointer points to a function that returns an integer value. The declaration of a pointer must be consistent with the declaration that it points to a function.
The parentheses around the pointer name and pointer operator change the default operator priority. Without parentheses, it becomes a prototype declaration of a function that returns an integer pointer.
Such as:
      Void FPTR (*) ();
Assigning the address of a function to a function pointer can take the following two forms:
              FPTR = & Function;
              FPTR = Function;
The take address operator & is not required because a single function identifier is numbered to indicate its address and, in the case of a function call, must contain a parenthesized list of arguments.
There are two ways to call a function through a pointer:
              X = (* FPTR) ();
              X = FPTR ();
The second format looks like a function call. But some programmers prefer the first format because it explicitly states that functions are called by Pointers, not by function names. Here's an example:


        void (*funcp)();
        void FileFunc(),EditFunc();
        main()
        {
            funcp=FileFunc;
            (*funcp)();
            funcp=EditFunc;
            (*funcp)();
        }
        void FileFunc()
        {
            printf("FileFunc/n");
        }
        void EditFunc()
        {
            printf("EditFunc/n");
        }

The output of the program is:
      FileFunc
      EditFunc

Three, the pointer pointer
The pointer to the pointer looks a little confusing. Their declaration has two asterisks. Such as:
              Char * * cp;
If there are three asterisks, that's the pointer to the pointer to the pointer, four asterisks are the pointer to the pointer to the pointer to the pointer, and so on.
Once you are familiar with simple examples, you can handle complex situations. Of course, in actual programs, only two Pointers are used, and three asterisks are not common, let alone four asterisks.
A pointer to a pointer requires the address of the pointer.
              Char c = 'A';
              Char * p = & c;
              Char * * cp = & p;
With a pointer to a pointer, you can access not only the pointer to which it points, but also the data to which it points. Here are a few examples:
              Char * p1 = * cp;     / / (& c)
              Char c1 = cp * *;
You might wonder what's the use of this structure? A pointer to a pointer allows the called function to modify local pointer variables and handle pointer arrays.


        void FindCredit(int **);
        main()
        {
            int vals[]={7,6,5,-4,3,2,1,0};
            int *fp=vals;
            FindCredit(&fp);
            printf(%d/n,*fp);
        }
        void FindCredit(int ** fpp)
        {
            while(**fpp!=0)
            if(**fpp<0) break;
            else (*fpp)++;
        }

The pointer fp is initialized with the address of an array, and the address of that pointer is passed as an argument to the function FindCredit(). The FindCredit() function gets the data in the array indirectly through the expression ** FPP.

To iterate over the array to find a negative value, the FindCredit() function augments itself with the caller's pointer to the array, not its own pointer to the caller's pointer. Statement (* FPP)++ is the pointer to the parameter pointer self - increment operation. But since the * operator is higher than the ++ operator, parentheses are required here, and if there are no parentheses, the ++ operator will be applied to the double pointer FPP.

Four, pointer to the pointer array
Pointer to another use of the old handle pointer array. Some programmers like to use pointer arrays instead of multidimensional arrays, and one common use is to work with strings.


        char *Names[]=
        {
             Bill,
             Sam,
             Jim,
             Paul,
             Charles,
             0
        };
        main()
        {
            char **nm=Names;
            while(*nm!=0) printf(%s/n,*nm++);
        }

The pointer nm is initialized with the address of the Names array of character Pointers. Each call to printf() first passes the character pointer that the pointer nm points to, and then self-increments the nm to point to the next element in the array (again, the pointer). Note that the completion of the above thought syntax is *nm++, which first gets the pointer to the content, and then makes the pointer self - increment.

Notice that the last element in the array is initialized to 0, and the while loop checks to see if it has reached the end of the array. A pointer with a zero value is often used as a terminator for a loop array. Programmers call NULL Pointers NULL Pointers. With a null pointer as the terminator, you don't have to change the code for traversing groups when tree species add or delete elements, because the array still ends with a null pointer.


Related articles: