Hier ist meine Meinung dazu:
Die Entwicklung der C-Sprache bietet einige Einblicke in die Entwicklung des Array-Typs in C:
Ich werde versuchen, das Array zu skizzieren:
Die Vorläufer B und BCPL von C hatten keinen bestimmten Array-Typ, eine Deklaration wie:
auto V[10] (B)
or
let V = vec 10 (BCPL)
würde V als (nicht typisierten) Zeiger deklarieren, der so initialisiert wird, dass er auf einen nicht verwendeten Bereich von 10 "Wörtern" Speicher zeigt. B bereits verwendet *
für Zeiger Dereferenzierung und hatte die []
verkürzte Schreibweise, *(V+i)
gemeint V[i]
, ebenso wie in C / C ++ heute. Ist V
jedoch kein Array, ist es immer noch ein Zeiger, der auf einen Speicher zeigen muss. Dies verursachte Probleme, als Dennis Ritchie versuchte, B mit Strukturtypen zu erweitern. Er wollte, dass Arrays Teil der Strukturen sind, wie in C heute:
struct {
int inumber;
char name[14];
};
Mit dem B, BCPL-Konzept von Arrays als Zeiger hätte das name
Feld jedoch einen Zeiger enthalten müssen, der zur Laufzeit auf einen Speicherbereich von 14 Bytes innerhalb der Struktur initialisiert werden musste . Das Initialisierungs- / Layoutproblem wurde schließlich gelöst, indem Arrays eine Sonderbehandlung gegeben wurden: Der Compiler verfolgte die Position von Arrays in Strukturen, auf dem Stapel usw., ohne dass der Zeiger auf die Daten tatsächlich materialisiert werden musste, außer in Ausdrücken, die die Arrays betreffen. Diese Behandlung ermöglichte es, dass fast der gesamte B-Code noch ausgeführt wird, und ist die Quelle der Regel "Arrays werden in Zeiger konvertiert, wenn Sie sie betrachten" . Es ist ein Kompatibilitäts-Hack, der sich als sehr praktisch herausstellte, da er Arrays mit offener Größe usw. erlaubte.
Und hier ist meine Vermutung, warum ein Array nicht zugewiesen werden kann: Da Arrays Zeiger in B waren, können Sie einfach schreiben:
auto V[10];
V=V+5;
ein "Array" neu zu gründen. Dies war jetzt bedeutungslos, da die Basis einer Array-Variablen kein Wert mehr war. Daher wurde diese Zuweisung nicht zugelassen, was dazu beitrug, die wenigen Programme zu erfassen, die diese Neuausrichtung auf deklarierten Arrays durchgeführt haben. Und dann blieb dieser Gedanke bestehen: Da Arrays niemals so konzipiert wurden, dass sie vom C-Typ-System erstklassig zitiert werden, wurden sie meist als spezielle Bestien behandelt, die zu Zeigern werden, wenn Sie sie verwenden. Und unter einem bestimmten Gesichtspunkt (der ignoriert, dass C-Arrays ein verpatzter Hack sind) ist es immer noch sinnvoll, die Array-Zuweisung nicht zuzulassen: Ein offenes Array oder ein Array-Funktionsparameter wird als Zeiger ohne Größeninformationen behandelt. Der Compiler verfügt nicht über die Informationen, um eine Array-Zuweisung für sie zu generieren, und die Zeigerzuweisung war aus Kompatibilitätsgründen erforderlich.
/* 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
}
Dies änderte sich nicht, als eine Überarbeitung von C 1978 die Strukturzuweisung hinzufügte ( http://cm.bell-labs.com/cm/cs/who/dmr/cchanges.pdf ). Obwohl Aufzeichnungen waren verschiedene Typen in C, es war nicht möglich , sie in frühen K & R C. Sie zuweisen hatte sie Mitglied weise mit memcpy zu kopieren und Sie nur Zeiger auf sie als Funktionsparameter übergeben konnte. Die Zuweisung (und Parameterübergabe) wurde nun einfach als Speicher des Rohspeichers der Struktur definiert, und da dies den vorhandenen Code nicht beschädigen konnte, wurde er leicht hinzugefügt. Als unbeabsichtigter Nebeneffekt führte dies implizit zu einer Art Array-Zuweisung, die jedoch irgendwo innerhalb einer Struktur auftrat, sodass dies nicht wirklich zu Problemen bei der Verwendung von Arrays führen konnte.