Reputation: 1621
#include <stdio.h>
void main()
{
int a[]={1,2,3,4};
printf("%u %u ",a ,&a); //a
printf("%d %d ", *a ,*&a); //b
}
In ath line the output of a
and &a
are same address but in bth line *&a
does not give me the answer as 1
.
I know that &a
means pointer to array of integers but as the address is same, it should print 1
right?
Upvotes: 2
Views: 119
Reputation: 6093
Please do one more thing in your code:
printf("%u %u ",a+1 ,&a+1); //a1
Upvotes: 0
Reputation: 2321
The latest draft of the C standard suggests that
If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted...
However, the above paragraph refers to the case when it's &*, not *&. Try to think of it this way:
&a // pointer to array[4] of integers
*(&a) // array[4] of integers
------------------------------------------
a // array[4] of integers
Note that the operator * removes single layer of pointers. Therefore, *(&a)
is identical to a
semantically. In this case, a
is converted to an expression with the type pointer to an integer
, because another paragraph suggests that
Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue...
In conclusion, the fact that the address of a
(not the element inside) is printed is natural.
Upvotes: 0
Reputation: 10560
Taking a simpler version of your code as follows:
#include <stdio.h>
void main()
{
int a[]={1,2,3,4};
printf("%d %d ", *a ,*&a); //b
}
If I compile that code I get this warnings:
test1.c
D:\Temp\test1.c(7): warning C4477:
'printf' : format string '%d' requires an argument of type 'int', but variadic
argument 2 has type 'int *'
Microsoft (R) Incremental Linker Version 14.00.23506.0
Copyright (C) Microsoft Corporation. All rights reserved.
That warning message gives you the reason why this is not working as you expect.
Now I can change that code to remove those warnings and I end up with code like this:
#include <stdio.h>
void main()
{
int a[]={1,2,3,4};
int (*p)[4] = &a;
printf("\n%u %u ", *a ,*p[0]); //b
}
That code clean compiles and when it is run you get the expected output:
1 1
Upvotes: 1
Reputation: 206567
a
decays to the pointer to the first element of the array.
&a
is the pointer to the array of 4 int
s.
Even though the numerical values of the two pointers are the same, the pointers are not of the same type.
Type of a
(after it decays to a pointer) is int*
.
Type of &a
is a pointer to an array of 4 int
s - int (*)[4]
.
Type of *a
is an int
.
Type of *&a
is an array of 4 ints - int [4]
, which decays to the pointer to the first element in your expression.
The call
printf("%d %d ", *a ,*&a);
is equivalent to:
printf("%d %d ", *a , a);
BTW, You should use %p
for pointers. Otherwise, you invoke undefined behavior. Increase the warning level of your compiler to avoid making such errors.
Upvotes: 6