On pointers and Arrays in C (Iv.)

Source: Internet
Author: User

Original Reprint Address: http://see.xidian.edu.cn/cpp/html/476.html

On the basis of the original text to add their own ideas as their own changes

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, and the number of bytes in the array is determined by the array itself. It is the abbreviation for "array of stored pointers".
Array pointer: First it is a pointer to an array. The 32-bit system will always be 4 bytes, as to how many bytes it points to, not known. 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:

two, int (*) [P2]-----Maybe you should. Define Array pointers

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.

Tips:
If you intend to perform any pointer operation on the pointer, you should avoid this type of declaration: int (*p) [] = matrix;p is still a pointer to an array of integers, but the length of the array is missing. When an integer with this type of pointer performs a pointer operation, its value is adjusted according to the length of the empty array (that is, multiplied by 0), and some compilers can find the error, and some do not. 

Three, the address of the casting

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 () {inta[4]={1,2,3,4}; int*ptr1= (int*) (&a+1); int*ptr2= (int*)((int) A +1); printf ("%x,%x", ptr1[-1],*ptr2); 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: Casts the value of &a+1 to the int* type and assigns the variable PTR1 to the int* type. 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 size and end mode of the system. 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;    1 ;    return (c.ch = =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.

On pointers and Arrays in C (Iv.)

Contact Us

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.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.