See the followingCode:
1 Int Main ( Int Argc, Char ** Argv) 2 { 3 Int A [ 5 ] = { 1 , 2 , 3 , 4 , 5 }; 4 Int * PTR = ( Int *) (& A + 1 ); 5 Printf ( " % D, % d \ n " , * (A + 1 ), * (PTR- 1 )); 6 Return 0 ; 7 }
This question is common in many so-called classical C language interview questions. Do you know the output result?
Answer:
However, many people still cannot answer the question, including me. This question is simple but not less than the following: Relationship between array pointer, array first address concept, array pointer and array first address and array first element address, pointer operation rules, pointer type, int type length, pointer length, type conversion... If one or more of these concepts is not so clear, it is easy to make a mistake.
To facilitate the discussion, first understand the following relationship:
The following is the result of a run on Ubuntu 10.10-desktop-i386 + GCC 4.4.5:
Size of A: 20 (bytes) (why? Because the machine is 32-bit, the size of Int Is 4 bytes, and a has 5 Int values)
Size of PTR: 4 (bytes) (PTR is a pointer, never forget, 32-bit long machine, pointer length is 4)
PTR address: bfb5c52c (depending on the specific situation, this is only for ease of understanding and discussion)
Address of A (& A): bfb5c518
Address of a [0]: bfb5c518
Address of a [1]: bfb5c51c
& A + 1: bfb5c52c (& A [0]: bfb5c518 -- & A [1]: bfb5c51c -- & A [2]: bfb5c520 -- & A [3]: bfb5c524 -- & A [4]: bfb5c528 -- & A [5]: bfb5c52c)
Note that & A [5] is only written here. It is actually out of the array range. Of course, it is legal to use array address a to obtain the address of a [5.
The following details:
- A is an array address. According to the C language semantics, that is, the address of the first element of the array. The first element is of the int type. Therefore, the address of the first element should be of the int * type, so the type of A is of the int * type *;
- & A is an array pointer. Its value is the same as that of a, but its meaning is different. That is, the type is different. Can you give the & A type accurately? It's int (*) [5]. Is it hard to understand? Do you still remember the type A mentioned in my article "applying for a two-dimensional array on the C stack? This is exactly what makes C language pointers obscure and difficult to understand.
If you understand these two points, the above problem is very simple:
A + 1: Now I think of a as a pointer, pointer + 1 operation. According to the C language semantics, the actual offset is the length of the pointer pointing type, that is, the int type under a 32-bit machine, 4 bytes, so a + 1 is & A [1], then * (a + 1) is a [1], that is, 2;
& A + 1: Now I think of & A as a pointer (I don't know how to "think "? INT (* B) [5] = & A), then the actual offset of & A + 1 is the length of its pointing type (INT (*) [5, that is, 20 bytes, so & A + 1 is actually a + 5, that is, & A [5] (although a [5] is out-of-bounds access, but & A [5] is not a problem, this is the C language ).
Now we know that the value of & A + 1 is a + 5, but its class is still int (*) [5], now PTR points to & A + 1 and is converted to int * by force type conversion, so what is the ptr-1? Because PTR is already of the int * type, the ptr-1 moves 4 bytes forward, that is, a + 4, that is, & A [4], then * (ptr-1) is a [4], that is, 5.
Is it very difficult? Come on. This is also the tip of the iceberg where C language is difficult and powerful.
The following link values (addresses) are the same:
A = & A [0]. If you don't believe it, try it!