Explanation of C pointer statements
2008-06-03 08:46
All the complex pointer declarations in C language are made up of various declarations nested. How can we interpret complex pointer declarations? The left-right rule is a well-known and commonly used method. However, the right-left rule is not actually the content in the C standard. It is a method summarized from the C standard statement. The C-standard declaration rules are used to solve how to create a declaration, while the right-left rule is used to identify a declaration. The two are the opposite. The original English version of the right-left rule is as follows:
The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. when you encounter parentheses, the direction shoshould be reversed. once everything in the parentheses has been parsed, jump out of it. continue till the whole declaration has been parsed.
The English translation is as follows:
Right-left rule: read from undefined identifiers in the parentheses in the innermost part, and then read from the right to the left. When parentheses are encountered, the reading direction should be dropped. Once everything in the parentheses is parsed, the parentheses appear. Repeat this process until the entire declaration is parsed.
In a word, the most fundamental method for analyzing statements is to compare and replace statements by priority and combination, and to simplify and understand the most basic statements. The following are several examples to illustrate how to use this method.
#1: int * (* a [5]) (int, char *);
First, we can see that the identifier a, "[]" has a higher priority than "*", and a and "[5]" are combined first. Therefore, a is an array with five elements. Each element is a pointer pointing to "int * (int, char *)". Obviously, it points to a function. The function parameter is "int, char *", and the return value is "int *". OK. :)
#2: void (* B [10]) (void (*)());
B is an array with 10 elements. Each element is a pointer pointing to a function. The function parameter is "void (*) ()". [Note: this is also a function pointer. If the parameter is null, void is returned. The return value is "void ". Finished!
#3: int (*) (* c) [9];
C is a pointer pointing to an array with nine elements. Each element is "int (*) ()" (that is, a function pointer pointing to a function, the parameter of this function is null, and the returned value is int type ).
#4: int (* d) [5]) (int *);
(* D) ------ pointer;
(* D) [5] ------ this pointer points to an array;
* (* D) [5] ------ each element in this array is of the pointer type;
Int (int *) ------ what type of pointer? This type.
#5: int (* e) (int *) [5];
* E ----- brackets to the right and brackets to the left * indicate that e is a pointer. What pointer?
(* E) (int *) ------ jump out of parentheses and encounter (int *) to the right. This indicates that this pointer is a function pointer and the form parameter is int *. Why is the return value? And listen to the next decomposition :);
* (* E) (int *) ------ what is the returned value? We encounter parentheses on the right, and then to the left. Oh, if we encounter *, we return a pointer. What pointer? Similarly, next decomposition;
(* E) (int *) [5] ------- [] to the right, indicating that it is a pointer to an array. What is an array? Don't worry, take it easy;
Int (* e) (int *) [5] ------- returns an int to the left. OVER
Of course, when a complex pointer needs to be declared, if the entire declaration is written in the form shown above, the readability of the program will be greatly impaired. If someone writes such a BT pointer statement, then the rp is really lost, and it is estimated that it will be scolded !.
Use typedef to separate the Declaration layer by layer to improve readability.
For example, for the above declaration: int (* func) (int *) [5]; it can be decomposed as follows:
Typedef int (* pArr) [5];
Typedef pArr (* func) (int *);
This makes it much easier to read!
What does that mean? Typedef int (* FUNC) (int *) [5]) (int *); ---- dizzy.
Actually typedef int (* FUNC) (int *) [5]) (int *);
Equivalent to the following :)
Typedef int (* PF) (int *);
Typedef PF (* PARRAY) [5];
Typedef PARRAY (* FUNC) (int *);
(* (Void (*) () 0) (); -------> what about this?
Follow the left and right rules:
(Void (*) () ----- is a function pointer prototype with a return value of void and a null parameter.
(Void (*) () 0 ----- convert the value of 0 to void. The parameter is a null function pointer and the Pointer Points to 0.
* (Void (*) () 0 ----- add * above to indicate the name of a function whose return value is void.
(* (Void (*) () 0) () ------ Of course this is a function call.
To simplify typedef:
Typedef void (* pf )();
(* (Pf) 0 )();
Author "programmer"