Meu primeiro palpite pelo motivo foi simplesmente por motivos de desempenho e economia de memória e também pela facilidade de implementação do compilador (especialmente para o tipo de computadores no momento em que C foi inventado). A passagem de grandes matrizes "por valor" parecia ter um grande impacto na pilha, ela precisa de uma operação de cópia de matriz completa para cada chamada de função e, provavelmente, o compilador deve ser mais inteligente para produzir o código de montagem correto (embora o último ponto seja discutível) . Também seria mais difícil tratar matrizes alocadas dinamicamente da mesma maneira que matrizes alocadas estaticamente (do ponto de vista da sintaxe do idioma).
EDIT: depois de ler algumas partes a partir deste link , eu acho que a razão real (ea razão pela qual matrizes em estruturas são tratados como tipos de valor, enquanto matrizes únicos não são) é a compatibilidade com versões anteriores ao do C predecessor B . Aqui está a citação de Dennis Ritchie:
[...} A solução constituiu o salto crucial na cadeia evolutiva entre o BCPL sem tipo e o tipo C. Ele eliminou a materialização do ponteiro no armazenamento e causou a criação do ponteiro quando o nome do array é mencionado em uma expressão. A regra, que sobrevive no C atual, é que os valores do tipo de matriz são convertidos, quando aparecem em expressões, em ponteiros para o primeiro dos objetos que compõem a matriz.
Esta invenção permitiu que a maioria dos códigos B existentes continuasse a funcionar, apesar da mudança subjacente na semântica da linguagem. [..]