I am a teaching assistant of a introductory programming course, and some students made this type of error:
char name[20];
scanf(\"%s\",&name);
In your example, the array test is a block of 50 ints. So it looks like this:
| int | int | ... | int |
When you apply the unary & operator to an array, you get the address of the array. Just like when you apply it to anything else, really. So &test is a pointer that points to that block of 50 ints:
(&test) -----------> | int | int | ... | int |
A pointer that points to an array of 50 ints has type int (*)[50] - that's the type of &test.
When you just use the name test in any place where it's not the operand of either the sizeof or unary-& operators, it is evaluated to a pointer to its first element. So the test that you pass to foo() evaluates to a pointer to the test[0] element:
(test) -----------------\
v
(&test) -----------> | int | int | ... | int |
You can see that these both are pointing to the same address - although &test is pointing to the whole array, and test is pointing to the first element of the array (which only shows up in the different types that those values have).