Beim Lesen des C ++ Primer-Buches stieß ich auf die folgende Aussage: "Die Anzahl der Elemente in einem Array ist Teil des Array-Typs." Also wollte ich das mit folgendem Code herausfinden:
#include<iostream>
int main()
{
char Array1[]{'H', 'e', 'l', 'p'};
char Array2[]{'P', 'l', 'e', 'a', 's', 'e'};
std::cout<<typeid(Array1).name()<<std::endl; //prints A4_c
std::cout<<typeid(Array2).name()<<std::endl; //prints A6_c
return 0;
}
Und interessanterweise zeigte das Ergebnis von typeid auf den beiden Arrays, dass sie irgendwie unterschiedlich sind.
- Was ist hinter den Kulissen los?
- Warum müssen Arrays einen Typ haben, der seine Größe enthält? Liegt es nur daran, dass sich seine Größe nicht ändern sollte?
- Wie wirkt sich dies auf den Vergleich von Arrays aus?
Ich möchte nur in der Lage sein, das Konzept tief zu verstehen.
Antworten:
Ein nicht dynamisch zugeordneter Container ist per Definition ein Container fester Größe mit homogenen Elementen. Eine Anordnung von
N
Elementen des TypsT
wird im Speicher als eine zusammenhängende Sequenz von angelegtenN
Objekten vom TypT
.Ich glaube nicht, dass es "notwendig" ist, dass der Typ eines Arrays seine Größe enthält - tatsächlich können Sie einen Zeiger verwenden, um auf eine zusammenhängende Folge von
T
Objekten zu verweisen . Ein solcher Zeiger würde Größeninformationen über das Array verlieren.Es ist jedoch eine nützliche Sache zu haben. Es verbessert die Typensicherheit und codiert nützliche Informationen zur Kompilierungszeit, die auf verschiedene Arten verwendet werden können. Beispielsweise können Sie Verweise auf Arrays verwenden , um Arrays unterschiedlicher Größe zu überladen
oder um die Größe eines Arrays als konstanten Ausdruck herauszufinden
Wirklich nicht.
Sie können Arrays im C-Stil nicht auf die gleiche Weise vergleichen, wie Sie zwei Zahlen (z
int
. B. Objekte) vergleichen würden . Sie müssten eine Art lexikografischen Vergleich schreiben und entscheiden, was dies für Sammlungen unterschiedlicher Größe bedeutet.std::vector<T>
vorausgesetzt, dass und die gleiche Logik auf Arrays angewendet werden kann.Bonus: C ++ 11 und höher bietet
std::array
einen Wrapper um ein Array im C-Stil mit einer containerähnlichen Oberfläche. Es sollte Arrays im C-Stil vorgezogen werden, da es mit anderen Containern (z. B.std::vector<T>
) konsistenter ist und auch sofort lexikografische Vergleiche unterstützt .quelle
std::equal
(viastd::begin
undstd::end
die für Arrays definiert sind). In diesem Fall sind Arrays unterschiedlicher Größe ungleich.Die Menge an Speicherplatz, die einem Objekt beim Erstellen zugewiesen wird, hängt vollständig von seinem Typ ab. Bei der Zuordnung handelt es sich nicht um Zuweisungen von
new
odermalloc
, sondern um den zugewiesenen Speicherplatz, damit Sie Ihren Konstruktor ausführen und Ihr Objekt initialisieren können.Wenn Sie eine Struktur definiert haben als (zum Beispiel)
Wenn Sie dann das Objekt konstruieren:
Sie können sich den Prozess des Konstruierens des Objekts als einen Prozess vorstellen:
'a'
und'b'
zum Objekt)Es ist wichtig zu beachten, dass die benötigten 2 Bytes Speicherplatz vollständig vom Typ des Objekts abhängen. Die Argumente für die Funktion spielen keine Rolle. Für ein Array ist der Prozess also der gleiche, außer dass jetzt der benötigte Speicherplatz von der Anzahl der Elemente im Array abhängt.
Die Arten von
a
undb
müssen die Tatsache widerspiegeln, dassa
genügend Platz für 1b
Zeichen und genügend Platz für 5 Zeichen benötigt wird. Dies bedeutet, dass sich die Größe dieser Arrays nicht plötzlich ändern kann. Sobald ein Array mit 5 Elementen erstellt wurde, handelt es sich immer um ein Array mit 5 Elementen. Um "Array" -ähnliche Objekte zu haben, bei denen die Größe variieren kann, benötigen Sie eine dynamische Speicherzuweisung, die Ihr Buch irgendwann abdecken sollte.quelle
Dies hat einen internen Grund für die Laufzeitbibliothek. Wenn Sie zum Beispiel die folgenden Aussagen berücksichtigen:
Dann wird klar, was das Problem ist: Zum Beispiel muss sich die Adressierung von
unsigned int *
mit dersizeof operator
oder Adressierung von befassenunsigned int
.Es gibt eine detailliertere Erklärung für den Rest dessen, was Sie hier sehen, aber es ist größtenteils eine Zusammenfassung dessen, was in der C-Programmiersprache, 2. Ausgabe von Kernighan und Ritchie über das Programm behandelt wurde, das den Klartext des deklarierten Typs druckt Zeichenfolge.
quelle