The name of an array is an alias of the address of the first element of the array*:
#include <stdio.h>
int main()
{
    int foo[5] = {2, 3, 4, 5, 6};
    int *bar = foo; 
    // now bar == foo, i.e. bar == &foo[0], so changing bar[2] changes foo[2]
    // bar[2] works because of pointer arithmetic
    printf("    foo is: %p\n",foo);     // prints the address of the first element of foo
    printf("&foo[0] is: %p\n", &foo[0]); // also prints the address of the first element of foo
    printf("    bar is: %p\n", bar);
    printf("&bar[0] is: %p\n", &bar[0]);
    printf(" foo[2] is: %d\n", foo[3]);
    printf(" bar[2] is: %d\n", bar[3]);
    return 0;
}
*with some exceptions. Namely sizeof foo != &foo[0]. See How come an array's address is equal to its value in C?
So when you wrote arr1 = arr2 the compiler thinks you are just referring to the address of the array not the whole array. When you write the name of a struct, the compiler knows you are referring to the struct as a whole, not just the first member.