I have been programming c/c++ for many years, but todays accidental discovery made me somewhat curious... Why does both outputs produce the same result in the code below? (<
They are not the same.
A bit more strict explanation:
arr is an lvalue of type int [3]. An attempt to use
arr in some expressions like cout << arr will result in lvalue-to-rvalue conversion which, as there are no rvalues of array type, will convert it to an rvalue of type int * and with the value equal to &arr[0]. This is what you can display.
&arr is an rvalue of type int (*)[3], pointing to the array object itself. No magic here :-) This pointer points to the same address as &arr[0] because the array object and its first member start in the exact same place in the memory. That's why you have the same result when printing them.
An easy way to confirm that they are different is comparing *(arr) and *(&arr): the first is an lvalue of type int and the second is an lvalue of type int[3].