Aquí está mi opinión sobre ella:
El desarrollo del lenguaje C ofrece una idea de la evolución del tipo de matriz en C:
I' Trataremos de delinear lo del arreglo:
Los precursores B de C y BCPL no tenían di stinct tipo de matriz, una declaración como:
auto V[10] (B)
or
let V = vec 10 (BCPL)
declararían V sea un puntero (sin tipo) que se inicializa para que apunte a una región no utilizada de 10 "palabras" de la memoria.B ya usó *
para la desreferenciación del puntero y tenía la notación abreviada []
, *(V+i)
significaba V[i]
, al igual que en C/C++ en la actualidad. Sin embargo, V
no es una matriz, sigue siendo un puntero que tiene que apuntar a cierta memoria. Esto causó problemas cuando Dennis Ritchie intentó extender B con tipos de estructuras. Quería matrices para formar parte de las estructuras, como en C Hoy:
struct {
int inumber;
char name[14];
};
Pero con el B, el concepto BCPL de matrices como punteros, esto habría requerido el campo name
para contener un puntero, que tenía que ser inicializado en el tiempo de ejecución a una región de memoria de 14 bytes dentro de la estructura. El problema de inicialización/disposición se resolvió finalmente dando a las matrices un tratamiento especial: el compilador rastrearía la ubicación de las matrices en las estructuras, en la pila, etc. sin requerir realmente que el puntero a los datos se materialice, excepto en expresiones que involucren las matrices. Este tratamiento permitió que casi todo el código B aún se ejecutara y es la fuente de las matrices "que se convierten en puntero si las mira" regla. Es un hack de compatiblity, que resultó ser muy útil, porque permitía matrices de tamaño abierto, etc.
Y aquí está mi suposición de por qué no se puede asignar una matriz: como las matrices eran punteros en B, simplemente podías escribir :
auto V[10];
V=V+5;
para volver a establecer una "matriz". Esto ahora no tenía sentido, porque la base de una variable de matriz ya no era un valor l. Por lo tanto, esta asignación no se permitió, lo que ayudó a detectar los pocos programas que hicieron este rebase en las matrices declaradas. Y luego, esta noción se atascó: como las matrices nunca fueron diseñadas para ser citestizadas de primera clase del sistema tipo C, fueron tratadas principalmente como bestias especiales que se convierten en punteros si las usas. Y desde cierto punto de vista (que ignora que los C-arrays son un hack fallido), no tener en cuenta la asignación de matrices aún tiene sentido: una matriz abierta o un parámetro de función de matriz se trata como un puntero sin información de tamaño. El compilador no tiene la información para generar una asignación de matriz para ellos y se requirió la asignación del puntero por razones de compatibilidad. La introducción de la asignación de matriz para las matrices declaradas habría introducido errores a través de asignaciones espurias (¿es una asignación ba = puntero o una copia de elementos?) Y otros problemas (¿cómo se pasa una matriz por valor?) Sin resolver un problema. Simplemente haga todo ¡explícito con memcpy!
/* Example how array assignment void make things even weirder in C/C++,
if we don't want to break existing code.
It's actually better to leave things as they are...
*/
typedef int vec[3];
void f(vec a, vec b)
{
vec x,y;
a=b; // pointer assignment
x=y; // NEW! element-wise assignment
a=x; // pointer assignment
x=a; // NEW! element-wise assignment
}
Esto no cambió cuando una revisión de C en 1978 añadió asignación struct (http://cm.bell-labs.com/cm/cs/who/dmr/cchanges.pdf). A pesar de que los registros eran tipos distintos en C, no fue posible asignarlos en K & R C temprano. Debes copiarlos a nivel de miembro con memcpy y solo puedes pasarles punteros como parámetros de función. La asignación (y el paso de parámetros) ahora simplemente se definía como la memcpy de la memoria en bruto de la estructura y, como esto no podía romper el código existente, se agregó fácilmente. Como efecto colateral involuntario, esto introdujo implícitamente algún tipo de asignación de matriz, pero esto sucedió en algún lugar dentro de una estructura, por lo que esto realmente no podría introducir problemas con la forma en que se utilizaron las matrices.
Estoy haciendo que esto tenga tanto C como C++ como etiquetas, porque esto se origina de C. Además, buena pregunta. – GManNickG
Puede valer la pena señalar que hace mucho tiempo en C, la asignación de estructura no era posible en general y que tenía que usar 'memcpy()' o similar. – ggg
¡Buena pregunta! –