Objective
First of all to declare some common sense, if you do not understand these common sense, please first to make up for the basic knowledge:
1, in fact, there is no multi-dimensional array, the so-called multi-dimensional array is essentially a one-dimensional array simulation.
2, the array name is a constant (meaning that it is not allowed to assign operations), which represents the first address of the first element of the array.
3, the relationship between the array and the pointer is because the array subscript operator [], for example, int a[3][2] is equivalent to * (* (a+3) +2).
4, the pointer is a variable, also has a type, it occupies memory space size and system-related, general 32-bit system, sizeof (pointer variable) = 4.
5. The pointer can add and subtract arithmetic operations, and the base unit of the addition and subtraction is sizeof (the type of data the pointer points to).
6, the array of arrays to take the name of the address (&) operation, the type is the entire array type.
7. Array names of arrays are operated with the sizeof operator, whose value is the size of the entire array in bytes.
8, the array is degraded to a pointer as a function parameter.
One or one-d array and array pointers
If there is one dimensional array as follows:
There are 3 elements in the array, the type of the element is char, and if you want to define a pointer to the array, that is, if you want to assign the array name A to a pointer variable, what is the type of the pointer variable? As previously stated, an array of arrays has an array name representing the first address of its first element, which is equivalent to &a[0], and the type of a[0] is char, so the &a[0] type is char *, so you can define the following pointer variable:
char * p = a;//equivalent to char * p = &a[0]
The above text can be represented in the following memory model diagram.
As we all know, a and &a[0] represent the first address of the first element of the array, and if you print the value of the &a, you will see that the value is equal to the first address of the first element of the array. Notice my wording here, that is, &a is equal to the value of the first address of the first element of the array, but its type is not the first address type of the first element of the array, that is, the char *p = &a is wrong.
As the 6th common sense has already said, the array name is taken to address operations, its type is the entire arrays, therefore, the type of &a is char (*) [3], so the correct assignment is as follows:
Note: Many people are confused about something similar to a+1,&a+1,&a[0]+1,sizeof (a), sizeof (&A), which can be solved simply by figuring out the type of pointer. For example, in the face of the difference between a+1 and &a+1, because a represents the first address of an array's first element and its type is char *, the a+1 corresponds to the array's first address value +sizeof (char), and the &a type is char (*) [3], which represents the entire array, so & The a+1 corresponds to the array's first address value +sizeof (a). (sizeof (a) represents the entire array size, as described in section 7th, but regardless of the size of the array, sizeof (&A) is always equal to the size of the space occupied by a pointer variable, specific to the system platform)
Two or two-d array and array pointers
If there are two dimensional arrays:
Because multidimensional arrays do not actually exist, you can view a[3][2] as a one-dimensional array of 3 elements, except that the three elements are a one-dimensional array. In fact, in memory, the array is indeed stored in the form of a one-dimensional array, stored in the order (low address in front): a[0][0], a[0][1], a[1][0], a[1][1, a[2][0], a[2][1. (This approach is also not absolute, there is a pattern of priority storage by column)
To make it easier to understand, I drew a logical memory graph, which is logically because the graph is just easy to understand, not the actual storage model of an array in memory (the actual model is described above).
As shown in the figure above, we can divide the array into two dimensions, first is the first dimension, the a[3][2] as a one-dimensional array of three elements, the elements are: a[0], a[1], a[2], of which, a[0], a[1, a[2] are a one-dimensional array with two elements, respectively ( Element type is char). From the second dimension, here you can see a[0], a[1], a[2] as an array name representing the "second dimension" array, A[0] as an example, A[0] (the array name) represents a one-dimensional array that has two char-type elements, and a[0 is the array name of the array ( Represents the first address of an array's first element, so the a[0] type is char *, and the same a[1] and a[2] types are char *. And a is the array name of the first-dimensional array, representing the first address of the first element, and the first element is a one-dimensional array of two char-type elements, so a is an array pointer to an array of two char-type elements, that is, char (*) [2].
In other words, the following assignment is correct:
char (*P) [2] = a;//a is the array name of the first dimensional array, the type is char (*) [2]
char * p = a[0];//a[0] The array name of the second dimension array, the type is char *
Similarly, a take-address operation represents the first address of the entire array, the type is an array type (let me call it that), which is char (*) [3][2], so the following assignment is correct:
Three or three-d array and array pointers
Suppose there are three-dimensional arrays:
Also, for ease of understanding, the following logical memory diagram is drawn. Parsing methods are similar to two-dimensional arrays, first, from the first-dimensional perspective, a[3][2][2] is a one-dimensional array of three elements a[0], a[1, a[2], except that the three elements are a "two-dimensional" array, a first-dimensional array name, representing the first address of the first element of the array, That is, an array pointer to a two-dimensional array of type char (*) [2][2]. Look at the past from the second dimension, A[0], a[1], a[2] is the array name of the second dimension array, representing the first address of the first element of the second dimension array, that is, an array pointer to a one-dimensional array, of type char (*) [2]; Similarly, look at the past from the third dimension, a[0][0], a[0][ 1], a[1][0], a[1][1], a[2][0], a[2][1, respectively, are the array names of the third dimensional array, representing the first address of the first element of the third dimension array, a pointer to the char type, and the type is char *.
From the above, the following assignment is correct:
char (*P) [3][2][2] = &a;//array name address type is the entire arrays
char (*p) [2][2] = A;
char (*P) [2] = a[0];//or a[1], a[2]
char *p = a[0][0];//or a[0][1], a[1][0] ...
Four: Multi-level pointers
The so-called multi-level pointer, is a pointer to the pointer, such as:
Char *p = "My name is Chenyang.";
Char **pp = &p;//Level two pointer
char ***PPP = &pp;//Level three pointer
Assuming that the above statements are in the body of the function, you can use the following simplified diagram to express the pointing relationship between the multilevel pointers.
Multilevel pointers are often used as parameters for functions, such as the common main function declaration:
int main (int argc,char * * argv)
Because when an array is used as the parameter of a function, it is degraded to a pointer, so the form above is the same as the following.
ARGV is used to receive command arguments entered by the user, which are passed in as an array of strings, similar to the following:
char * parm[] = {"Parm1", "Parm2", "parm3", "PARM4"};//simulate user incoming arguments
main (sizeof (PARM)/sizeof (char *), parm); The simulation calls the main function, in which the main function is called by the entry function (the entry function in glibc defaults to _start)
Another common use of multilevel pointers is to assume that a user wants to call a function to allocate a piece of memory, and that the allocated memory address can be obtained in two ways: the first is through the return value of the function, which declares the following function:
void * Get_memery (int size)
{
void *p = malloc (size);
return p;
}
The second way to get an address is to use a level two pointer with the following code:
int Get_memery (int** buf,int size)
{
*buf = (int *) malloc (size);
if (*buf = = NULL)
return-1;
else return
0;
}
int *p = NULL;
Get_memery (&p,10);
Summarize
The use of multi-level pointers is many, especially the two-level pointer is the most widely used, follow-up time to be supplemented. The content of multi-level pointers and multidimensional arrays in C + + to this is basically over, I hope the content of this article can be helpful to everyone.