Have you ever encountered a variable declaration like int * (* fp1) (int) [10]; that puzzles you? This article will show you how to understand this complex C/C ++ statement step by step. We will start with a simple declaration that we can encounter every day, and then gradually add the const modifier and typedef, as well as the function pointer, finally, we will introduce a "right-left rule" that allows you to accurately understand any C/C ++ statement ". It should be emphasized that the complex C/C ++ statements are not a good programming style. Here we only teach you how to understand these statements.
Let's start with a very simple example:
This should be understood as "declare n as an int" (n is an int type variable ). Next, let's take a look at the pointer variables as follows:
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 would like to discuss it here: I think it is best to write * (OR &) before it is near the variable when declaring a pointer (or reference) type variable, instead of following the basic type. This avoids some misunderstandings, such:
At first glance, it seems that p and q are both int * types, but in fact, only p is a pointer, and q is the simplest int type variable. Let's continue with our previous topic. Let's look at a pointer example:
Theoretically, there is no limit on the level of the pointer. You can define the pointer of a floating point type variable. Let's look at the following statement:
int RollNum[30][4]; int (*p)[4]=RollNum; int *q[5];
|
Here, p is declared as a pointer to a 4-element (int type) array, and q is declared as an array containing 5 elements (int type pointer. In addition, we can also mix and use * and & in the same declaration, 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. int &&p4;// ERROR: Reference to a reference is illegal.
|
Note: p1 is a pointer of the int type; p2 is a reference of the int type; p3 is a pointer of the int type reference (invalid !); P4 is a reference of the int type reference (invalid !).
Const Modifier
When you want to prevent a variable from being changed, the const keyword may be used. When you add a const modifier to a variable, you usually need to initialize it, because you will not have the opportunity to change it any time in the future. For example:
const int n=5; int const m=10;
|
The preceding two variables n and m are of the same type -- both are const int (integer constant ). According to the C ++ standard, the const keyword is equivalent before the type or variable name. I personally prefer the first declaration method because it highlights the role of the const modifier. Const and pointer are confusing. For example, let's take a look at the p and q statements in the pipeline:
const int *p; int const *q;
|
Which of them represents the const int type pointer (const directly modifies int), and which one represents the int type const pointer (const directly modifies the pointer )? In fact, both p and q are declared as const int type pointers. The const pointer of the int type should be declared as follows:
int * const r= &n;// n has been declared as an int
|
Here, both p and q point to the const int type pointer, that is, you cannot change * p value in future programs. R is a const pointer, Which is initialized to point to the variable n (that is, r = & n;) when declared, the r value is no longer allowed to be changed (but * The r value can be changed ).
In combination with the above two const modifiers, we declare a const pointer pointing to the const int type, as follows:
const int * const p=&n // n has been declared as const int
|
The following statements about const will help you thoroughly clarify the usage of const. However, note that the following statements cannot be compiled because they must be initialized at the same time. For the sake of conciseness, I ignored the initialization part. Because the initialization code is added, two lines of code will be added for each declaration below.
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
|
Note: p1 is the pointer to the char type; p2 is the pointer to the const char type; p3 is the const pointer to the char type; p4 is the const pointer to the const char type; p5 is the const pointer to the char type; p6 is the const pointer to the const pointer of the const char type; p7 is the const pointer to the const pointer of the char type; p8 is the const pointer to the const pointer of the const char type.
Typedef