I have encountered it to make you confused, similar to INT * (* (* (* fp1) (int)) [10]; Is this variable declaration? This article will be easy to be difficult, step by step, how do you understand this complex C / C declaration. We will start from a simpler statement that can be encountered every day, then gradually add const modifiers and TypeDef, and function pointers, and finally introduces a "right left law" that allows you to accurately understand any C / C declaration. It is necessary to emphasize that complex C / C declarations are not a good programming style; I just teach you how to understand these statements. Note: To ensure that code and related comments can be displayed on the same line, this paper is preferably read on a display of at least 1024x768 resolution. The basis allows us to start from a very simple example, as follows: int N; this should be understood as "declare n as an int" (n is an INT type variable). Let's take a look at the pointer variables, as follows: int * p; this should be understood as "declare p as an int *" (p is an int * type variable), or P is a pointer to an int type variable . I want to discuss here: I think it is best to write * (or &) before the variable is declared in a statement of a pointer (or reference) type, not followed by the basic type. This will avoid some misunderstandings, such as int * p, q; first look, it seems to be p and q are int * type, but in fact, only P is a pointer, and Q is the most Simple INT type variable. We still continue our topic, then look at a pointer to a pointer: char ** argv; theoretically, the number of stylus is not limited, you can define a pointer of the pointer of a pointer of a floating point type variable. .. then look at the following statement: int rollnum [30] [4]; int * p) [4] = rollnum; int * q [5]; Here, P is declared as a point 4 element (int type) Array pointer, while Q is declared as an array containing 5 elements (INT type pointers). In addition, we can also mix practical * and &, as follows: int ** p1; // p1 is a pointer to a pointer to an int. Int * & p2; // p2 is a reference to a Pointer to An Int. Int & * P3; // Error: Pointer To a Reference Is Illegal: Reference to a Reference Is IlleGal. Note: P1 is a pointer for an int type pointer; P2 is an int type The reference to the pointer; P3 is an int type reference pointer (not legal!); P4 is a reference to an int type reference (illegal!). Const modifier When you want to block a variable, it may be used to use the const key. While you have a variable plus const modifiers, you usually need to initialize it, because you will have no chance to change it at any time.
For example: const INT n = 5; int const m = 10; the above two variables N and M are actually the same type - all const INTs. Because the C standard specifies, the const keyword is equivalent to the type or variable name. I personally prefer the first declaration method because it highlights the role of const modifiers. It is easy for people to be confused when Const is working with a pointer. For example, let's take a look at the following P and Q: const INT * p; int const * q; which one represents the const Int type pointer (Const Direct Modification INT), which represents the int type const pointer ( CONST direct modified pointer)? In fact, P and Q are declared as a constent Int type pointer. The int * const r = & n; // n HAS been declared as an int here, P and Q are pointers to the Const Int type, that is, you are in the later program. You cannot change the value of * p. R is a const pointer, which is initialized to the variable N (ie R = & n;) after the declaration, the value of R will no longer be changed (but the value of * R can be changed). Combine the above two const modifications, let's declare a const pointer to the const Int type, as follows: Const Int * const p = & n// n HAS BEEN DECLARED AS Const Int below some of the declaration of Const, Help you completely clarify the use of consts. However, please note that some of the following statements cannot be compiled because they need to initialize while declaring. For the sake of simplicity, I ignore the initialization section; because the initialization code is added, each of the following declarations will add two lines of code.
Char ** p1; // Pointer to POINTER TO Char const char ** p2; // Pointer to POINTER TO Const char char * const * p3; // pointer to const p4; // Pointer TO Const Pointer to Const Char Char ** Const P5; // Const Pointer To 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 Point To const char Note: P1 is a pointer to a pointer to a CHAR type; P2 is a pointer to a pointer to a const char type; P3 is a constant to a CHAR type Pointer; P4 is a const pointer to the const char type; P5 is a const pointer to a pointer to a CHAR type; P6 is a const pointer to a CONST CHAR type pointer; P7 is a const pointer to a CHAR type const pointer; P8 is Const CONST pointer for a CONST pointer of a char type. Typedef's wonderful use of TypeDef to overcome "*" * only suitable for variables and is not suitable for type ". You can use typedef: typedef char * pchar; pchar p, q; the P and Q here are declared as pointers. (If you do not use Typedef, Q will be declared as a char variable, which is not consistent with our first eye!) There are some declarations using typedef, and give an explanation: typedef char * a; // a Is a pointer to a char typef ab (); // b is a function triapedef b * c; // c is a point to a function // That Returns a Pointer to a char Typedef CD (); // D is a function return // a Pointer to a function // That Returns a Pointe // 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 returbins to chars. TypeDef is often used before a structural declaration, as follows .
This way, when creating a structural variable, allow you to use the keyword structure (in C, create a struct key when creating a structural variable, such as Struct TagPoint A; in C , struct can ignore, such as tagpoint b). Typedef struct tagpoint {int x; int y;} Point; Point P; / * Valid c code * / Function pointer function pointer may be the most prone to understanding of the confusion. The function pointer is used up to the TSR program in the DOS time; in the Win32 and X-Windows era, they are used in the case where the callback function is required. Of course, there are many other places to use function pointer: virtual function table, some templates in STL, WIN NT / 2K / XP system service, etc. Let's take a look at a function of a function pointer: int (* p); here P is declared as a function pointer, this function with a char type parameter, and has an int type return value. In addition, there are two FLOAT type parameters, the return value is the function pointer of the pointer of the CHAR type pointer can be declared as follows: char ** (* p) (float, float); then with two CHAR type Const pointer parameters How do you declare the function pointer without reference? Reference is as follows: void * (* a [5]); "right left law" [important! ! ! ] The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left When you encounter parentheses, the direction should be reversed Once everything in the parentheses has been parsed, jump out of it Continue... Till The Whole Declaration Has Been Parsed. This is a simple rule, but you can make you accurately understand all the statements. This method is used as follows: From the most internal brackets, read the statement, look at it right, then look left left. When you encounter a parentheses, you will turn the direction of reading. All the contents in parentheses are analyzed and jumped out of the brackets. This continues until the entire statement is analyzed. Do a small correction for the above "right left law": When you start reading the statement for the first time, you must start from the variable name, not from the inside of parentheses. The following combine example to demonstrate the use of "right left default".
INT * (* (* fp1) (int)) [10]; reading steps: 1. From the variable name ----------------------- ------------------ fp1 2. Take the right, no, hit it), so see it, come to a * ------ one Pointer 3. Jump out of parentheses and meet (int) -------------------------------- a with an int Function of parameters 4. Look left, find one * -------------------------------------- - (function) Returns a pointer 5. Jump out of parentheses, look at it right, encounter [10] ------------------------------------------------------------------------------------------- - A 10 element array 6. Look left, find one * ------------------------------------------------------- ---- Pointing 7. Look left, discovery INT ----------------------- ---- Int Type Summary: FP1 is declared as an array of pointers of a function of a function, 10 elements, the prototype of the function is a parameter with an int type, the return value is a pointer? Let's take another example: int * (* arr [5]) ()) (); reading step: 1. Starting from the variable name ----------------- ------------------------ ARR 2. Look, find it is an array -------------- -------------------- A 5 element array 3. Look left, find one * ---------------- ----------------------- Pointer 4. Jump out of parentheses, look at it, discovery () -------------- ------------------ Do not use the parameters 5. Look left, touch * ------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------- (Function) Returns a pointer 6. Jump out of parentheses, discovery to right () ------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------- (function) Returns a pointer 8. Continue to the left and discover Int - ------------------------------------- int type summary: more example: float * (* b ()) []) (); // b is a function That Returns a // pointer to functions return floats. void * (* c) (char, int (*) ())