2
#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?

2
  • Read section 6 of the comp.lang.c. And void main() should be int main(void). And you're missing #include <stdio.h>. Commented Oct 8, 2016 at 4:57
  • Using %u in printf to print pointer values is undefined behavior (and it can easily lead to meaningless results in practice). There's %p specifically for printing pointers. And you should convert pointers to void * before sending them to printf. Commented Oct 8, 2016 at 6:32

4 Answers 4

6

a decays to the pointer to the first element of the array.
&a is the pointer to the array of 4 ints.

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 ints - 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.

Sign up to request clarification or add additional context in comments.

Comments

1

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 

Comments

0

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.

Comments

0

Please do one more thing in your code:

printf("%u %u ",a+1 ,&a+1); //a1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.