Array pointers (also called row pointers)
define INT (*p) [n];
() high priority, the first explanation is that p is a pointer to an integer one-dimensional array, the length of the one-dimensional array is n, it can be said that the step of P. In other words, when executing p+1, p crosses the length of n integer data.
To assign a two-dimensional array to a pointer, you should assign this value:
int a[3][4];
int (*p) [4]; The statement defines an array pointer to a one-dimensional array with 4 elements.
P=a; Assign the first address of the two-dimensional array to p, i.e. a[0] or &a[0][0]
p++; After the statement executes, that is, P=p+1;p crosses line a[0][] points to the line a[1][]
So an array pointer is also called a pointer to a one-dimensional array, also known as a row pointer.
Array of pointers
define int *p[n];
[] High priority, the first combination with P as an array, and then by int* that this is an integer pointer array, it has n pointer type array elements. When P+1 is executed, p points to the next array element, so that the assignment is wrong: P=a, because P is an unknown representation, only p[0], p[1], p[2]...p[n-1], and they are pointer variables that can be used to hold variable addresses. But can be so *p=a; Here *p represents the value of the first element of the pointer array, the value of the first address of a.
To assign a two-dimensional array to a pointer array:
int *p[3];
int a[3][4];
p++; The statement indicates that the P array points to the next array element. Note: Each element of this array is a pointer
for (i=0;i<3;i++)
P[i]=a[i]
Here int *p[3] indicates that a one-dimensional array holds three pointer variables, respectively p[0], p[1], p[2]
So you have to assign values separately.
So the difference between the two is enlightened, the array pointer is just a pointer variable, it seems that the C language is specifically used to point to a two-dimensional array, it occupies memory of a pointer to the storage space. Pointer arrays are multiple pointer variables that exist in the form of an array of memory, occupying multiple pointers of storage space.
It is also important to note that both the reference and the array name reference are the same when used to point to a two-dimensional array.
For example, to represent an array of I row J columns of an element:
* (P[I]+J), * (* (p+i) +j), (* (P+i)) [j], P[i][j]
Priority: () >[]>*
=========================================================================
Memory layout of pointer arrays and arrays of pointers
Beginners always can't tell the difference between a pointer array and an array pointer. In fact, very well understood:
Array of pointers: first it is an array, the elements of the array are pointers, the number of bytes of the array is determined by the size of the array itself, each element is a pointer, and any type of pointer under a 32-bit system is always 4 bytes. It is the abbreviation for "array of stored pointers".
Array pointer: First it is a pointer to an array. Any type of pointer under a 32-bit system is always 4 bytes, as to how many bytes it points to, not knowing, the size of the array. It is the abbreviation for "pointers to arrays".
Which of the following is an array pointer, which is an array of pointers:
A
int *p1[10];
B
int (*P2) [10];
Every time I ask this question in class, there is always something unclear. Here you need to understand the priority problem between a symbol.
The priority of "[]" is higher than "*". P1 is first combined with "[]" to form the definition of an array, with the array named P1,int * decorated with the contents of the array, that is, each element of the array. Now we know that this is an array that contains 10 pointers to data of type int, that is, an array of pointers. As for P2, it is better understood that the precedence of "()" Here is higher than "[]", "*" and P2 constitute a pointer definition, and the pointer variable named P2,int modifies the contents of the array, that is, each element of the array. The array does not have a name here and is an anonymous array. So now we know that P2 is a pointer to an array that contains 10 data of type int, that is, an array pointer. We can use the following diagram to deepen our understanding:
II, INT (*) [ten] P2-----Maybe you should define an array pointer like this
Here's an interesting topic to explore: do we usually define pointers with pointer variable names after data types? How is the definition of this pointer p2 not defined by this syntax? Maybe we should define P2:
Int (*) [ten] p2;
Int (*) [10] is a pointer type, p2 is a pointer variable. It looks really good, but it's a little awkward. In fact, the array pointer prototype is really like this, but for convenience and good-looking to the pointer variable P2 forward. You can totally understand this in private. Although the compiler does not think so. ^_^
Thirdly, the difference between a and &a
In that case, the problem came. Before we talk about the difference between a and &a, now take a look at the following code:
int main ()
{
Char a[5]={' A ', ' B ', ' C ', ' D '};
char (*P3) [5] = &a;
char (*P4) [5] = A;
return 0;
}
Which is correct for the use of P3 and P4? What is the value of p3+1? What is the value of p4+1? There is no doubt that both P3 and P4 are array pointers, pointing to the entire array. &a is the first address of the entire array, and a is the first address of the first element of the array with the same values but different meanings. In C language, the data types on both sides of the assignment symbol "=" must be the same, if different need to show or implicitly type conversion. P3 the data types on both sides of this defined "=" are exactly the same, and the data types on both sides of the "=" sign P4 this definition are inconsistent. The type on the left is a pointer to the entire array, and the data type to the right is a pointer to a single character. The following warning is given on visual c++6.0:
Warning C4047: ' Initializing ': ' char (*) [5] ' differs in levels of indirection from ' char * '.
Fortunately, the warning is given here, but since &a is the same as the value of a, the compiler simply takes the value of the variable as the right value, so there is nothing wrong with running it. But I still warn you not to use it.
Now that it's clear that P3 and P4 all point to the entire array, the values of p3+1 and p4+1 are well understood.
But what if you change the code and change the size of the array to a smaller point? What is the value of p3+1 and p4+1?
int main ()
{
Char a[5]={' A ', ' B ', ' C ', ' D '};
char (*P3) [3] = &a;
char (*P4) [3] = A;
return 0;
}
You can even modify the code to change the size of the array to a larger point:
int main ()
{
Char a[5]={' A ', ' B ', ' C ', ' D '};
char (*P3) [Ten] = &a;
char (*P4) [ten] = A;
return 0;
}
What kind of problems will there be at this time? What is the value of p3+1 and p4+1?
The above questions, I hope the reader can carefully consider, and the machine test to see the results.
Test results:
(1). Char (*P2) [5]=a; must use cast, such as: char (*P2) [5]= (char (*) [5]) A;
(2). Change the size of the array, will compile does not pass, prompt:
Error C2440: ' Initializing ': cannot convert from ' char (*) [5] ' to ' char (*) [3] '
Error C2440: ' Initializing ': cannot convert from ' char (*) [5] ' to ' char (*) [10] '
(3). Put the above program test code as follows:
int main ()
{
Char a[5]={' A ', ' B ', ' C ', ' d '};
char (*P1) [5]= &a;
char (*P2) [5]= (char (*) [5]) A;
printf ("a=%d\n", a);
printf ("a=%c\n", a[0]);
printf ("p1=%c\n", **P1);
printf ("p2=%c\n", **P2);
printf ("p1+1=%c\n", * * (p1+1));
printf ("p2+1=%c\n", * * (p2+1));
return 0;
}
Output:
a=1638208
A=a
P1=a
P2=a
P1+1=?
P2+1=?
Press any key to continue
Conclusion:
The pointer size is represented by the pointer type and the object, and each increment of 1 indicates a byte that increases the size of the pointer type. There will be an explanation later----.
Iv. forced conversion of addresses
Let's look at the following example:
struct Test
{
int Num;
Char *pcname;
Short sdate;
Char cha[2];
Short sba[4];
}*p;
Suppose the value of P is 0x100000. What are the values of the following table expressions?
p + 0x1 = 0x___?
(unsigned long) p + 0x1 = 0x___?
(unsigned int*) p + 0x1 = 0x___?
I believe there will be a lot of people in the beginning not to understand what this problem means. In fact, we take a closer look, this knowledge point familiar. A pointer variable is added to an integer minus, so how do you parse it?
Remember the difference between the expression "a+1" and "&a+1" in front of us? Actually, it's the same here. The pointer variable is added to an integer minus the integer that is not directly added to the address in the pointer variable. The unit of this integer is not a byte but the number of elements. So: the value of P + 0x1 is 0x100000+sizof (Test) *0x1. As for the size of this structure is 20byte, the previous chapters have been explained in detail. So the value of P +0x1 is: 0x100014.
(unsigned long) p + 0x1 value? This involves casting, which forces the value saved by the pointer variable p to be cast to the unsigned long integer. Once a value is cast, its type is changed. So the expression is actually an unsigned long integer plus another integer. So its value is: 0x100001.
(unsigned int*) p + 0x1 value? The p here is cast to a pointer to an unsigned integer. So its value is: 0x100000+sizof (unsigned int) *0x1, equals 0x100004.
The above question seems to have no technical content, the following is a technical content: under the x86 system, what is the value?
Intmain ()
{
int a[4]={1,2,3,4};
int *ptr1= (int *) (&a+1);//point to the memory cell behind the A array, &a+1 means to move backward by 16 storage units
int *ptr2= (int *) ((int) a+1);//The address of the storage unit of a adds one byte
printf ("%x,%x", PTR1[-1],*PTR2);//ptr1[-1] actually points to the last cell of the A array, and *PTR1 represents the value stored by the 4 contiguous storage units after the address of the A array moves one byte after the other
return 0;
}
This is my lecture class A student asked my question, he saw on the internet, said to have baffled n individuals. After I read the question, I told him that these people certainly do not understand the Assembly, a person who understands the assembly, the problem is a small case. Here's an analysis of the problem:
According to the above explanation, the difference between &a+1 and a+1 is clear.
PTR1: Cast the value of &a+1 to the int* type, the variable ptr,ptr1 assigned to the int* type will definitely refer to the next int type data of array A. PTR1[-1] is parsed into a * (ptr1-1), that is, ptr1 backwards 4 byte. So its value is 0x4.
PTR2: As explained above, the value of (int) a+1 is the address of the second byte of the element a[0]. The address is then coerced to the value of the int* type to ptr2, meaning that the value of *ptr2 should be 4 bytes in a row starting with the second byte of the element a[0].
Its memory layout is as follows:
Okay, here's the question, what's in the 4 bytes in a row? This means that the value of the element a[0],a[1] is stored in the end. This involves the system's size and end mode, which is not a problem if the assembly is understood. Since you do not know what the current system is, you have to try to test it. The size-and-end mode and test methods have been discussed in detail in the first chapter on the Union keyword, please turn to the other side to see, here is no longer detailed. We can use this function to test the mode of the current system.
int Checksystem ()
{
Union check
{
int i;
Char ch;
C
C.I. = 1;
Return (c.ch ==1);//If the current system is in the big-endian mode this function returns 0; if it is a small-end mode, the function returns 1.
}
If the current system is in the big-endian mode This function returns 0, and if the small-end mode, the function returns 1. This means that if the return value of this function is 1, the value of *PTR2 is 0x2000000. If the return value of this function is 0, the value of *PTR2 is 0x100.
The difference between an array pointer and an array of pointers