问题
I got the output for the following code as -> 6
I was confused by the output, so I changed a small portion of code and checked it.
I substituted this int * ptr=(int*)(a+1)
for the Not clear statement, I got the output as --> 1
. How?
I heard &a
, a
, a[0]
all are same address? what makes it different?
#include<stdio.h>
int main()
{
int a[] = {1, 2, 3, 4, 5, 6};
int *ptr = (int*)(&a+1); //NOT CLEAR
printf("%d ", *(ptr-1) );
getchar();
return 0;
}
回答1:
Like many other developers, you are confused by decay. The following code is valid, because a
will implicitly decay to a pointer:
int a[] = {1,2,3};
int* b = a;
Decay is what notably allows arrays to implicitly transform into pointers to their first elements.
However, the following code is not valid, because decay is not the same as taking the address of the array:
int a[] = {1,2,3};
int* b = &a; // INVALID
The first example gets you a pointer to an integer (the first integer in the array). In the second example, &a
gets you a pointer to an array of 3 integers. If you had to assign it to a variable, its type would be:
int a[] = {1,2,3};
int (*b)[3] = &a;
The alien form should show you that this is not what you expect at all.
It is true that a
(once decayed), &a
and &a[0]
should all point to the same address. However, they do not point to the same kind of thing (&a
points to an array, while the others point to integers).
The result of pointer operations depend at least as much on the type of the pointer as to the value of the pointer. Each time you increase that &a
pointer by 1, you move by three integers in memory, not just one, because the size of the type is (3 * size of an integer). This is what happens when you do (&a + 1)
, and this is why you get an unexpected result. There is no value defined at this memory address, so you get undefined behavior.
It compiles because you cast the pointer to an int pointer, and if you want my advice, you should never silence compiler warnings about pointers with casts.
回答2:
Let's look at memory!
| * | * | 1 | 2 | 3 | 4 | 5 | 6 | * | * |
^ ^ ^ ^
| | | |
(a) | | (&a + 1)
(a + 1) |
(((int *)(&a + 1)) - 1)
回答3:
Array is a collection of similar data types stored in contiguous Memory location.
Array name represents the base address. a
, &a
and &a[0]
all are points to starting address of the array only.
But In your code when you are doing (Consider starting address of the array is 1000)
int * ptr=(int*)(a+1)
- it points to second element in the array(1004). printf("%d ", *(ptr-1) );
which prints first element, Because in printf you decremented the array address
int * ptr=(int*)(&a+1)
- It will points to Next array(that is 1024).
printf("%d ", *(ptr-1) );
- prints the element at the location of 1020(that is 6)
int main()
{
int a[] = {1, 2, 3, 4, 5, 6};
int *ptr = (int*)(&a+1); // Ptr will point to Starting address of next array. &a+1 increments the whole array size.
printf("%d ", *(ptr-1) ); // Due to contiguous memory, when printing you decrements one element. so it prints 6.
getchar();
return 0;
}
来源:https://stackoverflow.com/questions/25008826/what-is-the-difference-between-a-a0-a-in-c