Home>

I didn't fully understand the concept of array before,I just think the array name is just a constant pointer.Usage is similar to basic pointers.So when I try to use a secondary pointer to access a two-dimensional array,You often make mistakes.Here is a wrong program I just started writing:

#include<stdio.h>
int main ()
{
    int iarray [2] [3]={{1,2,3}, {4,5,6}};
    int ** parray=null;
    parray=iarray;
    printf ("array [0] [0] =%d \ n", parray [0] [0]);
    printf ("array [1] [2] =%d \ n", parray [1] [2]);
    return 0;
}

At the beginning, I analyzed it like this:arrays and pointers are almost the same,One-dimensional array corresponds to one-dimensional pointer,Then the two-dimensional array name should be similar to the two-dimensional pointer.So the above program is not wrong,It should print 1 and 6. But when I actually compile and run,But there was a segmentation fault,That is, I accessed the address space that should not be accessed.What went wrong?How should the correct program be written?

To solve the problem,I have to re-understand the meaning of array.After flipping through some books,I found that arrays are not as simple as I thought:a collection of variables identified by a constant pointer.An array should also be considered a complete variable type:there is a name, a size, and an address.It's just that the name is the same as its address.Because of the size of the array,So when using sizeof to operate on the array name,Calculated is the size of the actual array,Not the size of the pointer.

Because of this,So pointers to arrays are also very different from pointers to pointers.The most obvious difference between them is when the pointer steps.We know that when pointers are performing ++ operations,The actual address of the jump depends on the type of data pointed to by the pointer:For a typical 32-bit machine,If it points to int type data, the actual address spanned is 4, and it points to pointer type data.The actual address straddled is also 4, when pointing to an array type,The actual address spanned is the length of the array.

Now go back and analyze the error program above,According to the operation rules of the subscript reference symbol [],We know that parray [0] [0] is actually ** parray, and iarray is actually just an array variable name.And its value is the starting address of the entire array (in fact&iarray, iarray, iarray [0] and&iarray are the starting address of the array,Are all values ​​assigned by the compiler during compilation). In fact, * parray is already the value of iarray [0] [0], which is 1, and ** parray is to access the data in the address space with address 1.A paragraph error will naturally occur.

Its practical pointer to access the two-dimensional array can be directly used by the first-level pointer.For example, the following program:

int main ()
{
    int iarray [2] [3]={{1,2,3}, {4,5,6}};
    int * parray=null;
    parray=iarray;
    printf ("array [0] [0] =%d \ n", * parray);
    printf ("array [1] [2] =%d \ n", * (parray + 1 * 3 + 2));
    return 0;
}

Because the array itself is continuously arranged in the address space,Based on the number of rows and columns,Calculating the address offset of the access unit by ourselves can easily traverse all the data in the two-dimensional array with the first-level pointer.

We can also try to access the members of a two-dimensional array with a pointer to the array.Here is the example program:

int main ()
{
    int iarray [2] [3]={{1,2,3}, {4,5,6}};
    int (* parray) [3]=null;
    parray=iarray;
    printf ("array [0] [0] =%d \ n", parray [0] [0]);
    printf ("array [1] [2] =%d \ n", parray [1] [2]);
    return 0;
}

A brief analysis of this program:we know that the combining direction of the [] operator is from left to right,parray [1] [2] is equivalent to (* (parray + 1)) [2], and because parray is an array pointer,And the length of the array is 3, so * (parray + 1) means iarray [1].Then parray [1] [2] is exactly equivalent to iarray [1] [2].

If you have to use a secondary pointer to access a two-dimensional array,We also have to borrow an array of pointers (the array stores all pointer-type data). Here is a sample program:

int main ()
{
    int iarray [2] [3]={{1,2,3}, {4,5,6}};
    int * iparray [2]={iarray [0], iarray [1]};
    int ** parray=null;
    parray=iparray;
    printf ("array [0] [0] =%d \ n", parray [0] [0]);
    printf ("array [1] [2] =%d \ n", parray [1] [2]);
    return 0;
}

Since the secondary pointer has to jump twice,So in the middle, it needs extra space to store pointers.So it is generally not recommended to use a secondary pointer to access a two-dimensional array.

As we all know,Pointers are essentially addresses! The address of a variable is called the "pointer" to the variable. If there is such a variable:its storage unit stores the addresses of other variables! We call it "pointer variable". (Note the difference between the two:two completely different concepts!)

we all know,Array names and function names are their entry addresses.Similarly, a variable name is actually the address of the variable! There is an operator in the C language:"&":addressing operator.Because array names and function names themselves represent addresses,They usually do not and cannot perform addressing operations or other arithmetic operations (in fact, direct references to function names are equivalent to addressing them). That's why they are called "constants"! But for a variable,The situation is different.To get its address,You must perform the "&" operation, although it itself also represents the address value! And directly referencing the variable to get the data content of the memory unit it is in! "Pointer variable" as a variable is of course no exception! It's just different from other ordinary variables,Its content is the address of other variables (including "pointer variables"). On win32, its size is always 32 bits and 4 bytes. There is no limit on the size of ordinary variables! The data content of the address pointed to by the pointer variable is obtained through the operator "*". We understand the "withdrawal operator *" as part of the type,And this data type is a variable address type (both for each "*")!

As long as you understand the above common sense,"Pointer" will no longer be a "stopper" in programming!

From the perspective of memory mapping,The regular array of c (excluding multi-dimensional arrays designed by data structures) does not exist multi-dimensional,In other words, all arrays are one-dimensional in nature,The first-level pointer is equivalent to a one-dimensional array! The key difference is the semantic difference between multi-dimensional arrays and one-dimensional arrays! And we understand that multidimensional arrays are usually described as "matrix". A more precise understanding is that each element of a multidimensional array is an array,Recursively until each element is a simple variable type,The end result is a special one-dimensional array!

c
  • Previous C # implement App icon with message count
  • Next Method to solve the problem that angular $httppost () cannot receive parameter values ​​when submitting data in the background