How to interpret complex C/C + + statements
Article catalog
I think many people have encountered declarations like int * (* fp1) (int) [10], or similar things you can't understand? This article will teach you to explain such complex C/C + + declarations, including the use of typing, const and function fingers.
order
Have you ever encountered something like this. int * (* (*fp1) (int) ) [10]; And can't understand? This article will teach you to explain the C/C + + declaration from easy to difficult, from simple c language declaration, const modifier, typedef modifier, function pointer, and finally to the "left and right rule". The purpose of this article is to help understand the declaration of c language. It is not recommended to follow the c programming specification like the code in this article.
1. Foundation
Let me start with a very simple example. Consider the statement:
int n;
Declare n as an int type
int *p;
Declare p as a pointer of type int, which the author suggests in the original text
int *p
instead of
int* p
This individual thinks that unification is good.
You can also declare pointers to pointers
char **argv;
In principle, there are no restrictions on the usage, which means that you can have a finger pointing to finger to finger, but usually the secondary pointer is difficult to understand.
Consider the following statement:
int RollNum[30][4]; int (*p)[4]=RollNum; int *q[5];
p is declared as a pointer that points to an array of type int, the size of which is 4. If p + + is executed; Increase the value of p by 4*sizeof(int) q is declared as an array. The contents of the array store pointers. What pointers? All pointers point to data of type int.
2. const modifier
When you want to prevent modifying a variable (which seems contradictory), you can use the const keyword. When declaring a const variable in c language, you need to initialize the variable, otherwise it cannot be assigned elsewhere.
const int n=5; int const m=10;
Two variables are of the same type - constant integer. This is because the C + + standard specifies that keywords can be placed before types or variable names. Personally, I prefer the former style because it makes the modifier clearer.
But const and pointers are relatively difficult to understand.
const int *p; int const *q;
Which of them points to one and which points to one? In fact, they all point to int types. Both p and q point to const int, which means that the value pointing to the variable cannot be changed.
int * const r= &n; // n has been declared as an int
Here r is a const pointer, which points to n during initialization, so the following statement is illegal.
r=&m;
however
*r=4;
Yes. However, if the following statement is declared:
const int * const p=&n; // n has been declared as const int
English: declare a const pointer to a const int, the pointer is const, and the variable is const, which cannot be changed during operation. Only initialization can be assigned.
Some statements are listed below for reference:
char ** p1; // pointer to pointer to char const char **p2; // pointer to pointer to const char char * const * p3; // pointer to const pointer to char const char * const * p4; // pointer to const pointer to const char char ** const p5; // const pointer to pointer to char const char ** const p6; // const pointer to pointer to const char char * const * const p7; // const pointer to const pointer to char const char * const * const p8; // const pointer to const pointer to const char
3. Subtleties of typedef
Look directly at the code:
typedef char * PCHAR; PCHAR p,q;
Both p and q are defined as char * types.
Here are some usage methods and explanations of typedef:
typedef char * a; // a is a pointer to a char typedef a b(); // b is a function that returns // a pointer to a char typedef b *c; // c is a pointer to a function // that returns a pointer to a char typedef c d(); // d is a function returning // a pointer to a function // that returns a pointer to a char typedef d *e; // e is a pointer to a function // returning a pointer to a // function that returns a // pointer to a char e var[10]; // var is an array of 10 pointers to // functions returning pointers to // functions returning pointers to chars.
typedef is also common in structure type definitions
typedef struct tagPOINT { int x; int y; }POINT; POINT p; /*Valid C code */
4. Function pointer
Function pointers are relatively difficult to understand. In dos in primitive times, win32 in modern times and x-windows, it is often used in callback functions. Virtual function table in c + +, STL template, and Win NT/2K/XP system services, etc. A simple example of a function finger:
int (*p)(char); void * (*a[5])(char * const, char * const);
Declare p as a pointer to a function whose parameter is char and return value is int
Declare a as an array of function pointers, and each element in the array points to a
Contains two char*const Pointer, return value is void*Function of
Function pointer to
5 left right rule
This is a simple rule that allows interpretation of any declaration. The specific explanations are as follows:
Read the statement from the innermost parentheses, go right, then left. When parentheses are encountered, the direction should be opposite. Once everything in parentheses has been parsed, it jumps out. Then continue until the entire declaration is resolved.
A note about the rules: the first time you start reading a declaration, you must start with the identifier, not the innermost parentheses.
give an example:
int * (* (*fp1) (int) ) [10];
Click the following steps to start the process:
Start with identifier -------------------fp1 On the right is ) ,Look left and right, I found it*---fp1 Is a pointer Jump out()I met him later(int) ------------The pointer points to a function, one of which int parameter Look left, I found it * ---------------This function returns a pointer Jump out(), Look right, I found it [10] ----The returned pointer points to an array of 10 elements Look left, I found it * ---------------Array elements are pointers Look to the left, find int -------------Each array element points to int type
The anatomy is complete Complete explanation in English:
Start from the variable name -------------------------- fp1 Nothing to right but ) so go left to find * -------------- is a pointer Jump out of parentheses and encounter (int) --------- to a function that takes an int as argument Go left, find * ---------------------------------------- and returns a pointer Jump put of parentheses, go right and hit [10] -------- to an array of 10 Go left find * ----------------------------------------- pointers to Go left again, find int -------------------------------- ints.
declare fp1 as pointer to function (int) returning pointer to array 10 of pointer to int
Another exercise:
int *( *( *arr[5])())();
Start with identifier -----------------arr right,find[5] -----------------arr Is an array of 5 elements Look left, find * ---------------Each element is a pointer Jump out(), Look right, I found it() ------Each pointer points to a function, that is, the array element is a function pointer Look left, find * --------------- The function pointed to returns a pointer Jump out(), Look right, I found it() -------The return value points to the function Look left, find * ---------------Function return pointer Keep looking left, find int ----------Pointer pointing int Type data.
The anatomy is complete Complete explanation in English:
Start from the variable name --------------------- arr Go right, find array subscript --------------------- is an array of 5 Go left, find * ----------------------------------- pointers Jump out of parentheses, go right to find () ------ to functions Go left, encounter * ----------------------------- that return pointers Jump out, go right, find () ----------------------- to functions Go left, find * ----------------------------------- that return pointers Continue left, find int ----------------------------- to ints.
declare arr as array 5 of pointer to function returning pointer to function returning pointer to int
List some complex c statements and explanations for learning:
float ( * ( *b()) [] )(); // b is a function that returns a // pointer to an array of pointers // to functions returning floats. void * ( *c) ( char, int (*)()); // c is a pointer to a function that takes // two parameters: // a char and a pointer to a // function that takes no // parameters and returns // an int // and returns a pointer to void. void ** (*d) (int &, char **(*)(char *, char **)); // d is a pointer to a function that takes // two parameters: // a reference to an int and a pointer // to a function that takes two parameters: // a pointer to a char and a pointer // to a pointer to a char // and returns a pointer to a pointer // to a char // and returns a pointer to a pointer to void float ( * ( * e[10]) (int &) ) [5]; // e is an array of 10 pointers to // functions that take a single // reference to an int as an argument // and return pointers to // an array of 5 floats.
Original link: How to interpret complex C/C++ declarations