This is because of the decay of arrays into pointers.
In most contexts, when an array name is used it decays to a pointer to the first element of the array. That's what's happening when you pass str
to printf
. One of the few times this decay doesn't happen is when the array is the subject of the address-of operator &
. This gives the address of the array itself, which has the same value as the address of the first element. That's why the printed value is the same.
This conversion is detailed in section 6.3.2.1 of the C standard:
3 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. If
the array object has register storage class, the behavior is
undefined.
Although the types of the two expressions are different (one is char *
and the other is char (*)[50]
), the values of the two pointers are the same.