«Address of» (&) массив / адрес игнорируемого be gcc?

Я ассистент вводного курса по программированию, и некоторые студенты допустили такую ​​ошибку:

char name[20];
scanf("%s",&name);

что неудивительно, поскольку они учатся ... Что удивительно, что, кроме предупреждения gcc, код работает (по крайней мере, эта часть). Я пытался понять, и я написал следующий код:

void foo(int *v1, int *v2) {
  if (v1 == v2)
    printf("Both pointers are the same\n");
  else
    printf("They are not the same\n");
}

int main() {
  int test[50];
  foo(&test, test);
  if (&test == test)
    printf("Both pointers are the same\n");
  else
    printf("They are not the same\n");
}

Компиляция и выполнение:

$ gcc test.c -g
test.c: In function ‘main’:
test.c:12: warning: passing argument 1 of ‘foo’ from incompatible pointer type
test.c:13: warning: comparison of distinct pointer types lacks a cast
$ ./a.out 
Both pointers are the same
Both pointers are the same

Может кто-нибудь объяснить, почему они не отличаются?

Я подозреваю, что это потому, что я не могу получить адрес массива (как я не могу иметь& &x), но в этом случае код не должен компилироваться.

Изменить: Я знаю, что массив сам по себе совпадает с адресом первого элемента, но я думаю, что это не связано с этой проблемой. Например:

int main() {
  int a[50];
  int * p = a;
  printf("%d %d %d\n", p == a, p == &a[0], &p[0] == a);
  printf("%d %d %d\n", p == &a, &p == a, &p == &a);
}

печатает:

$ ./a.out 
1 1 1
1 0 0

Я не понимаю, почему вторая строка начинается с1.

Ответы на вопрос(5)

Ваш ответ на вопрос