There is a very good article about the right left law , the original Link.
int *p[4]; An array of Pointers. is an array of 4 elements, each of which is a pointer to an integral type . (each element of an array is a pointer)
int (*p) [4]; An array pointer. It is a pointer to an array of 4 integral Elements. (a Pointer to an array with 4 integral elements)
int *func (void); Pointer Function. A parameterless function that returns an integer pointer. (the return value of the function is Int*)
int (*func) (void); Represents a function pointer, which can point to a function that has no parameters and returns a value of an integer pointer. (the return value of the function is Int)
Right-left rule:
Because all of the complex pointer declarations in the C language are composed of various declarations Nested. How to interpret complex pointer declarations? Right-left Law is a well-known and commonly used Method. however, the Right-to-left method
is not in fact the content of the C standard, it is from the C standard of the Declaration of the method summed up. The C Standard's declaration rules are used to solve how to create a declaration, while the right-hand rule is
To resolve how to discern a statement, the two can be said to be the Opposite. The English text of the Right-to-left law is said:
The Right-left Rule:start reading the declaration from the innermost parentheses, go right, and then go to left. When you
Encounter parentheses, The direction should be Reversed. Once everything in the parentheses have been
parsed, jump out of it. Continue till the whole declaration has been Parsed.
This English translation is as Follows:
Right-to-left rule: start with the innermost parentheses (undefined identifiers), then look right and look left. Whenever you encounter parentheses, you should reverse the direction of Reading. Once you have finished parsing all the parentheses inside, jump out of the Parentheses. Repeat this process until the entire declaration
Parsing is Complete.
I would like to make a small amendment to this rule, should be not defined by the identifier to start reading, rather than from the parentheses read, the reason is undefined identifier, because there may be multiple identifiers in a declaration, but the undefined identifier will only have ONE.
now, with some examples to discuss the application of Right-to-left law, Let's start with the simplest, and gradually deepen:
int (*func) (int *p);
First find the undefined identifier, is func, it has a pair of parentheses outside, and the left is an * number, which means that Func is a pointer, and then jump out of this parenthesis, first look at
The right side is also a parenthesis, which means (*func) is a function, and func is a pointer to such a function, which is a function pointer, such a function has a int* type of formal parameter, the return value type is int.
int (*func) (int *p, int (*f) (int*));
Func is enclosed by a pair of parentheses, and there is an * number on the left, indicating that Func is a pointer, out of parentheses, and a parenthesis to the right, then Func is a pointer to a function that has a formal parameter such as int * and int (*) (int*), and the return value is
The int type. Then take a look at the func parameter int (*f) (int*), similar to the previous explanation, F is also a function pointer, the function that points to has a int* type of formal parameter, the return value is int.
int (*func[5]) (int *p);
The right side of the Func is a [] operator, stating that Func is an array with 5 elements, and the left side of the Func has a *, indicating that the element of Func is a pointer, and that this is not a modifier of func, but a modification of func[5], because [] operator precedence
Higher than *, func is first combined with [], so the modifier is func[5]. Jumping out of this parenthesis, looking to the right, is also a pair of parentheses, stating that the element of the Func array is a pointer to the function type, the function it points to has a int* type parameter, and the return value type is
Int.
int (* (*func) [5]) (int *p);
Func is enclosed by a parenthesis, and there is another * on the left, then Func is a pointer, out of parentheses, to the right is a [] operation symbol, indicating that Func is a pointer to an array, now to the left, there is an * sign on the left, indicating that the element of this array is
pointer, then out of parentheses, and a parenthesis to the right, indicating that the element of the array is a pointer to the Function. To summarize, that is: func is a pointer to an array, the elements of which are function pointers, which point to a int* parameter,
A function that returns a value of type int.
int (* (*func) (int *p)) [5];
Func is a function pointer that has a formal parameter of type int*, and the return value is a pointer to an array, and the element of the array that is pointed to is an array with 5 int elements.
It is important to note that some complex pointer declarations are illegal, such as:
int func (void) [5];
Func is a function that returns a value that has an array of 5 int elements. however, the function return value of the C language cannot be an array, because if the function returns the value array, then the object that receives the contents of this array must also be a list, but the C language
The array name is an rvalue, it cannot be an lvalue to receive another array, so the function return value cannot be array.
int func[5] (void);
Func is an array of 5 elements, and the elements of this array are functions. This is also illegal, because the elements of an array must be the same in addition to the type, each element occupies the same memory space, obviously the function does not meet this requirement,
Even though the type of the function is the same, the space occupied by the function is usually not the Same.
In practice, when a complex pointer needs to be declared, it is a major detriment to the readability of the program if the entire declaration is written in the form shown Above. A typedef should be used to layer the Declaration.
Decomposition to enhance readability, for example for declarations:
int (* (*func) (int *p)) [5];
Can be decomposed like this:
typedef int (*PARA) [5];
typedef PARA (*FUNC) (int *);
This makes it easier to See.
The answer, at the same time, gives a method of decomposition using Typedef:
int (* (*func) [5][6]) [7][8];
Func is a pointer to an array whose elements are a two-dimensional array with 5x6 int elements, and the element of this two-dimensional array is a two-dimensional array.
typedef int (*PARA) [7][8];
typedef PARA (*FUNC) [5][6];
int (* (* (*func) (int *)) [5]) (int *);
Func is a function pointer, and the return value of such a function is a pointer to an array, the element that points to the array is also a function pointer, the function that points to has the int* parameter, and the return value is int.
typedef int (*PARA1) (int*);
typedef PARA1 (*PARA2) [5];
typedef PARA2 (*FUNC) (int*);
int (* (*func[7][8][9]) (int*)) [5];
Func is an array whose elements are function pointers, which have int* formal parameters, the return value is a pointer to an array, and the element of the array that is pointed to has 5 int elements
The Array.
typedef int (*PARA1) [5];
typedef PARA1 (*PARA2) (int*);
typedef PARA2 func[7][8][9];
Pointer array array pointer pointer function function pointer