Teach you to understand complex CC ++ declarations

xiaoxiao2021-03-06  100

Lu Qi Ming translated into the original text:

http://www.codeproject.com/cpp/complex_declarations.asp

Author: Vikram A Punathambekar introduction had come across so that you puzzled, like int * (* (* fp1) (int)) [10]; such variables declared it? This article will be easily difficult, step by step, how do you understand this complex C / C declaration: We will start from a simple statement you can encounter every day, then gradually add const modifiers and typedef, and function pointer, Finally, an "right left definition" 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 origency to a pointer to An int.int & * p3; // error: Pointer to a reference is illegal.int && p4; // error: 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 modifications 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 P2; // Pointer to POINTER TO Const Charchar * const * p3; // Pointer to const p4; // Pointer to const P4; // Pointer To Const Pointer To const charchar ** const p5; // const power to pointer to charconst char ** const p6; // const Pointer to POINTER TO Const Charchar * const * const p7; // const Pointer to const Pointer to Charconst Char * Const * Const P8; // Const Poin Note: P1 is a pointer to a pointer to a CHAR type; P2 is a pointer to the CONST CHAR type pointer; P3 is a const pointer to a CHAR type; P4 is Const Char Type const pointer; 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 a Const CHAR type Const pointer constant pointer. 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 chartypedef a b (); // b Is a function truRNS // a Pointer to a chartypedef b * c; // c is a pointer to a function // That Returns a Pointe to a chartypedef c d (); // D is a function Returning // That Returns a Pointer to a chartypedef d * e; // e is a pointer to a function // return a Pointer to a // function That Returns a // pointer to a chare var [10]; // var is an array of 10 Pointers to // functions return Pointers to chars.typedef is often used in 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 declaration. 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. Starting from the variable name ----------------------- ------------------ fp12. Go to the right, nothing, touched it), so see it, come to a * ------ a pointer 3. Jump out of parentheses and meet (int) --------------------------------- A with an int parameter Function 4. Look left, find one * ------------------------- (Function) Returns a pointer 5. Jump out of parentheses, look at it right, encounter [10] ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- An array of 10 elements 6. Look left, find a * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Pointer 7. Look to the left, discovery int -------------------------------------- --- int Type Summary: FP1 is declared as an array of pointers of a function of a function, this array has 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 ----------------- ------------------------ ARR2. Tour right, found is an array --------------- ------------------- A 5-element array 3. Look left, find a * ----------------- ---------------------- Pointer 4. Jump out of parentheses, look at it, discovery () --------------- ----------------- Do not with parameters 5. Look left, touch * ------------------- ------------------------ (function) Returns a pointer 6. Jump out of parentheses, discover () to right () ---------- -------------------------- Do not use the parameters 7. Left, discovery * ------------ -------------------------------- (function) Returns a pointer 8. Continue to the left, discover Int --- ----------------------------------- int ration summary:? ? There are more examples: float (* (* b ()) []) (); // b is a function That Returns a // pointer to functions returnid floats.void * (* c) (char, int (*));

转载请注明原文地址:https://www.9cbs.com/read-124434.html

New Post(0)