For starters it is a bad idea to cast an address to the type int like
cout << (int)&a << endl;
you could just write
cout << static_cast<void *>( a ) << endl;
or
cout << static_cast<void *>( &a ) << endl;
Or even like
cout << a << endl;
cout << &a << endl;
though with static_cast the code looks more readable.
The both statements will output the same value: the address of the extent of memory occupied by the array.
In this function call
Func(a);
the array designator is implicitly converted to pointer to its first element of the type int( * )[3].
The value of the pointer expression is assigned to the local variable (parameter) a of the function Func.
The function parameter of the pointer type a and the array a defined in main occupy different extents of memory.
If to rename the function parameter as for example
void Func(int b[2][3])
to distinguish it from the array with the same name defined in main then you may imagine the function call the following way
Func(a);
//...
void Func( /*int b[2][3] */ )
{
int ( *b )[3] = a;
cout << static_cast<void *>( &b );
}
Pay attention to that the function parameter declared as having the array type int[2][3] is implicitly adjusted by the compiler to pointer to the array element type that is int ( * )[3].
So as you can see this statement
cout << static_cast<void *>( &b );
outputs the address of the local variable (parameter) b.
If you want to get the address of the array a within the function Func then you should write
cout << static_cast<void *>( b );
In this case the addresses outputted in main and in the function will coincide because the parameter b stores the address of the first element of the array a.
Here is a demonstration program.
#include <iostream>
void Func( int a[2][3] )
{
std::cout << static_cast< void * >( a ) << '\n';
}
int main()
{
int a[2][3] =
{
{1,2,3},
{4,5,6}
};
std::cout << static_cast<void *>( a ) << '\n';
std::cout << static_cast<void *>( &a ) << '\n';
Func( a );
}
The program output might look like
010FFD08
010FFD08
010FFD08
As you can see the three values are equal each other.
But if you will write in the function Func
std::cout << static_cast< void * >( &a ) << '\n';
^^^^
you will get the address of the local variable (parameter) a of the function. It is evident that this address differs from the address of the extent of memory occupied by the array because for the parameter a there was allocated a separate extent of memory the size of which is equal tp the value of the sizeof( int( * )[3] ) and usually this value is equal to 4 or 8.
aby value (even if it decays to a pointer, that pointer is still passed by value)cout << static_cast<void const*>(&a). The reason is that it makes it clearer what's going on and further it avoids the special cases for character pointers.b? Repeating the same variable name may be reinforcing the incorrect notion that they are the same variable.std::arrayandstd::vectoron top of legacy c arraysa(cout <<(int) a) instead of its location. Also, look at&a[0]inmain.