C-language multidimensional arrays and multilevel pointers
Source: Internet
Author: User
multidimensional arrays and multi-level pointers are also a place for beginners to feel confused. Arrays with more than two dimensions and pointers exceeding two levels are actually not much used. If we can figure out the two-dimensional array and the two-level pointer, then the two-dimensional is not a problem. So this section focuses on two-dimensional arrays and two-level pointers.
one or two-D array1, the imaginary two-dimensional array layout
As we discussed earlier, you can save any data in an array except the function. The following is a detailed discussion of the stored array inside the array. Excel table, I believe we have all seen. We can usually imagine a two-dimensional array as an Excel table, such as:
Char a[3][4];
2, the comparison between the memory and the ruler
In fact, the memory is not a table, but linear. Have you seen the ruler? The ruler is very similar to our memory. The minimum scale of a ruler is millimeters, and the minimum unit of memory is 1 byte. Normally we say 32 millimeters, which means to start with a zero offset of 32 mm; Usually we say the memory address is 0x0000ff00 is also refers to from the memory 0 address to offset 0x0000ff00 byte. Since memory is linear, the two-dimensional array must be stored linearly in memory. In fact, its memory layout is the following figure:
Accesses an element of one of these elements in the form of an array subscript: a[i][j]. The compiler always regards a two-dimensional array as a one-dimensional array, and each element of a one-dimensional array is an array. A[3] The three elements of this one-dimensional array are:
A[0],A[1],A[2]. The size of each element is sizeof (a[0]), that is, Sizof (char) *4. The first addresses of the a[0],a[1],a[2] three elements can be computed as & a[0],& a[0]+ 1*sizof (char) *4,& a[0]+ (char) 2*sizof respectively. The first address of A[i] is & a[0]+ i*sizof (char) *4. Then consider the contents of a[i]. For the purposes of this example, A[i] has 4 char-type elements with the first address of each element being &a[i],&a[i]+1*sizof (char), &a[i]+2*sizof (char) &a[i]+3*sizof (char), that is, the first address of A[i][j] is &a[i]+j*sizof (char). Then the value of &a[i] is represented by a, and the first address of the A[I][J element is: A + i*sizof (char) *4+ j*sizof (char). Similarly, it can be converted into a pointer representation: * (* (a+i) +j).
After the above explanation, I believe you have mastered the two-dimensional array in memory layout. Here is a question to read:
#include <stdio.h>
Intmain (int Argc,char * argv[])
{
int a [3][2]={(0,1), (2,3), (4,5)};
int *p;
p=a [0];
printf ("%d", p[0]);
}
Ask how much the results are printed out.
A lot of people think this is too easy, soon can tell me the answer: 0. But it's a pity, it's wrong. The answer should be 1. If you think it is 0, you should take a good look at this problem. The curly braces are nested with parentheses, not curly braces. Here is a comma expression nested inside the curly braces. In fact, this assignment is equivalent to
int a [3][2]={1, 3,5};
So, when initializing a two-dimensional array, be careful not to accidentally write curly braces in parentheses.
Out.
3, &p[4][2]-&a[4][2] is the value of the number.
The above question seems to be relatively well understood, let's look at one more example:
int a[5][5];
int (*p) [4];
p = A;
Ask &p[4][2]-the value of &a[4][2] is how much.
The question seems very simple, but few people have answered it correctly. We can first write the code to test its value and then analyze why. In Visual c++6.0, the test code is as follows:
Intmain ()
{
int a[5][5];
int (*p) [4];
p = A;
printf ("a_ptr=% #p, p_ptr=% #p \ n", &a[4][2],&p[4][2]);
printf ("%p,%d\n", &p[4][2]-&a[4][2],&p[4][2]-&a[4][2]);
return 0;
}
After testing, we know that the value of &p[4][2]-&a[4][2] is-4. What the hell is this about? Let's analyze the following: As we said earlier, when array name A is the right value, it represents the first address of the first element of the array. Here, A is a two-dimensional array, we think of array A as a one-dimensional array of 5 int type elements, which stores a one-dimensional array.
So, then a is here to represent the first address of a[0]. A+1 represents the second element of a one-dimensional array a. A[4] Represents the 5th element of a one-dimensional array a, and a one-dimensional array is stored in the element. So &a[4][2] represents the &a[0][0]+4*5*sizeof (int) + 2*sizeof (int).
By definition, p is a pointer to an array that contains 4 elements. In other words, p+1 represents a pointer p moving backward with an array of 4 int types of elements. The unit of 1 here is the space that P points to, that is, 4*sizeof (int). Therefore, P[4] is moved backwards by 4 "arrays of 4 INT-type elements", that is, &p[0]+4*4*sizeof (int), as opposed to p[0. Because P is initialized to &a[0], &p[4][2] represents the &a[0][0]+4*4*sizeof (int) +2* sizeof (int).
Again, the values of &p[4][2] and &a[4][2] differ by 4 elements of type int, as described above. Now, the test results are understandable. In fact, our easiest way is to draw the memory layout diagram:
The most important thing here is to understand exactly what memory the array pointer p is pointing to. The best way to solve this type of problem is to draw a memory layout diagram.
二、二级 PointerMemory layout for 1, level two pointers
Second-level pointers are often used, especially when they are together with two-dimensional arrays, which is even more confusing. For example:
Char **p;
Defines a two-level pointer variable p. P is a pointer variable, which undoubtedly occupies 4 byte under 32-bit systems.
Unlike a first-level pointer, the primary pointer holds the address of the data, and the two-level pointer holds the address of a level pointer. The following figure helps to understand: we try to initialize the variable p:
A
p = NULL;
B
Char *p2; p = &p2;
Any pointer variable can be initialized to null (note is NULL, not nul, NOT null), and level two pointers are no exception. This means pointing the pointer at the 0 address of the array. Lenovo to the front we compare the ruler to memory, if the memory is initialized to NULL, it is the equivalent of pointing the pointer to 0 millimeters on the ruler, at which point the pointer has no memory available.
When we really need to use p, we have to save the address of a first-level pointer to P, so B is also the correct way to assign the value.
Assigning p is no problem, but how to use P. This requires the key ("*") that we have mentioned many times before.
The first step: according to the variable of p, take out the address stored in it.
Step Two: Locate the memory in which this address resides.
Step three: Open the memory with the key, take out the address inside it, *p the value.
Step Fourth: Find this address for the second time.
The fifth step: Open this memory with the key, take out the content inside it, this is our real data, **p value.
We used the key two times here ("*") to finally get the real data out. That is, to remove the data that the two-level pointer actually points to, you need to use the key ("*") two times two times.
For more than two-d arrays and more than two-d pointers are generally used less, and according to the above analysis method can also be very easy to understand, this is no longer discussed in detail. If readers are interested, they can study.
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.