Cuando declaras una matriz en C, ¿por qué la matriz y la matriz * regresan a la misma dirección? ¿Por qué no sucede esto cuando asigna la matriz?

Porque en la mayoría de los contextos en C, un identificador que nombra un objeto de matriz, o una constante de matriz literal, se convierte automáticamente en un puntero a su primer elemento (cero). Las declaraciones de matrices y sus inicializadores son una excepción; otro es el operando de “sizeof”. La indexación de matrices no es una excepción.

Para ser confuso, se supone (correctamente) que los argumentos de función ya se han colapsado de esta manera. Una declaración de parámetro puede verse como una declaración de matriz sin contraer, pero se trata como el puntero correspondiente. En su mayoría no lo notará, pero “sizeof” le dará el tamaño del puntero, no de la matriz.

Ahora, volviendo a su pregunta exacta; no hay tal cosa como una “matriz” en C. Me imagino que te refieres a una matriz de algún tipo, muy probablemente con dos dimensiones declaradas. Cualquier cosa que termine apuntando a la matriz, o a la matriz seguida de cualquier número disponible de índices cero, será un puntero al inicio de la matriz; la dirección será la misma, incluso si el tipo de puntero es diferente en los diferentes niveles de indexación. Todos menos los dos niveles más bajos posibles de indexación le permiten hacer esto:

x identifica una matriz de dimensión> = 2

Aquí, x puede ser una expresión que implica indexación y desreferencia de puntero en un identificador de matriz.

En la mayoría de los contextos de expresión, x se contrae en un puntero al miembro cero de la matriz (es decir, que apunta a una matriz de dimensión> = 1)

* x identifica una matriz de dimensión> = 1

En la mayoría de los contextos de expresión, * x se contrae en un puntero al primer elemento de la matriz de dimensión> = 1.

Observe que estos diversos valores intermedios de matriz y puntero no tienen el mismo tipo.