C++: immer die Zeile die Größe eines mehrdimensionalen Arrays an eine Funktion übergeben
Ich versuche, eine Funktion schreiben, die druckt den Inhalt eines mehrdimensionalen Arrays. Ich weiß, die Größe der Spalten, jedoch nicht die Größe der Zeilen.
EDIT: Da ich nicht klar machen werden die arrays, die an diese Funktion übergeben werden NICHT dynamisch zugeteilt. Die Größen sind zur Kompilierzeit bekannt ist.
Teste ich es mit einem 3x2 Arrays. Hier ist die Funktion so wie es da steht:
void printArrays(int array1[][2], int array2[][2]) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
cout << "\narray1[" << i << "][" << j << "] = "
<< setfill('0') << setw(2) << array1[i][j]
<< "\tarray2[" << i << "][" << j << "] = "
<< setfill('0') << setw(2) << array2[i][j];
}
}
}
Offensichtlich funktioniert dies nur, wenn ich weiß, die Größe von "i" ist 3 (es ist in diesem Fall). Ideal, jedoch möchte ich die Funktion zu arbeiten, egal, was die Größe der ersten dimension.
Ich dachte, ich wäre in der Lage, dies zu tun mit der sizeof () - Funktion, z.B.
int size = sizeof(array1);
... und tun Sie etwas Mathematik aus.
Hier ist der ungerade Teil. Wenn ich den sizeof () - Funktion in das array, gibt es einen Wert von 4. Ich kann verwenden Sie Zeiger-notation auf die array-Dereferenzierung:
int size = sizeof(*array1);
... aber das wirklich gibt einen Wert von 8. Dies ist merkwürdig, da die Gesamt Größe sollte Zeilen(die = 3) * Spalten(= 2) * sizeof(int), (= 4), oder 24. Und in der Tat, dies ist das Ergebnis, wenn ich sizeof(*array1) außerhalb der Funktion.
Weiß jemand, was ist hier Los? Noch wichtiger ist, hat jemand eine Lösung?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die Antwort ist, dass Sie dies nicht tun können. Sie müssen übergeben Sie die Anzahl der Zeilen, die als argument an die Funktion, oder verwenden Sie einen STL-container wie
std::vector
oderstd::array
.sizeof
berechnet compile-Zeit;sizeof
ist nie hilfreich bei der Bestimmung der dynamische Größe von Objekten in C/C++. Sie (selbst Programmierer) kann immer berechnensizeof(x)
nur aus der Betrachtung der code-und header-Dateien, dasizeof
zählt die Anzahl der bytes, die zur Darstellung des Objekts.sizeof(*array1)
werden immer 8, daarray1[i]
ist ein array von zweiints
und4==sizeof(int)
. Wenn Sie erklärenint array1[][2]
dies entsprichtint *array1[2]
. Das istarray1
ist ein Zeiger auf array von zwei Integer-zahlen.sizeof(array1)
ist daher 4 bytes, da dauert es 4 Byte und auf Ihrem Computer repräsentieren einen Zeiger.*array1
ist ein integer-array mit genau zwei Elementen.array1[i]
entspricht*(array1+i)
.Erreichen Sie dies, bis zu einem gewissen Grad durch die Verwendung von Vorlagen Funktionen. Die Vorbehalte sind:
Ich bin Arbeitsform den code auf diesem blog-post von Kevin Heifner.
Können Sie die Größe der beiden arrays mit template-Magie:
Dies funktioniert nur für arrays, deren Grenzen zum Zeitpunkt der Kompilierung bekannt und nicht für dynamisch zugewiesenen arrays.
In jedem Fall: Sie sollten
std::vector
oderboost::multiarray
.Die Größe ist 8, die außerhalb der Funktion, da Sie dereferenzieren das erste array, das gibt Ihnen die Spalte Größe (2) mal die Größe eines
int
(4). Wenn Sie wollten, 24, würde Siesizeof(array)
(außerhalb der Funktion). Die Antwort ist 4 innen die Funktion, weil es behandeltarray
wie ein Zeiger, der auf die Größe von 4 bytes.Jedoch zuverlässig die Größe von arrays, die übergeben wurden, - Funktionen, Sie müssen entweder im pass der Größe oder so etwas wie
vector
.Einen sehr einfachen Weg, es zu tun, ohne dass Vektoren, templates, Klassen, oder übergeben Sie die Größe des Arrays, wird eine Letzte Zeile der Daten enthält etwas einzigartiges, wie im folgenden Beispiel, wo eine -1 wird in der letzten Zeile, erste Spalte:
Dann nur brechen aus der Schleife(N), wenn Sie erreichen, dass einzigartige Wert:
Verwenden Sie einfach besser arrays!
Was ich damit meine ist, können Sie machen Sie Ihre eigene array-Klasse die wraps ein array, oder verwenden Sie einige gemeinsame Bibliotheken mit solchen Klassen (z.B. boost). Dies ist viel sicherer, und wahrscheinlich ist es leichter, sich Gedanken darüber zu machen, dass gerade C++ - arrays.
Ein Grund dafür ist, wenn Ihr schreiben die Funktion
Sie haben tatsächlich nicht so viele Garantien, die auf das array, wie Sie vielleicht denken. Zum Beispiel, es ist nicht garantiert, dass die zweite dimension des Arrays zwei Elemente breit (ich könnte falsch sein, über diesen Punkt, da ich keine Referenzen zur hand, aber ich bin ziemlich zuversichtlich, dass es). Dies ist, da die eigentliche Signatur für die Funktion ist
Dies ist, da arrays zu degenerieren Zeiger beim Einsatz in Funktions-Deklarationen (das ist, warum Sie
sizeof(array)
gibt 4, da 4 bytes ist die Größe einer Zeiger-Typ auf Ihrem Computer). Auch Sie klar haben keine Garantie auf die Größe der ersten dimension, also der Annahme, es geht um 3 ist gefährlich, und möglicherweise das Ergebnis der verwirrenden Fehlern in der Zukunft.Dies ist, wo eine benutzerdefinierte
array
Klasse, wäre toll, vor allem, wenn es wurden Vorlagen. Zum Beispiel, ein zwei-dimensionales array der Klasse deklariert werden könnte, wieVerwendung solcher Ansatz ermöglicht die Pflege alle die Informationen über das array in alle situation, z.B.
Nun können Sie entscheiden, die Größen, die jede dimension des Arrays.
Zusätzlichen Vorteil, dass Sie hinzufügen können bounds checking, um Ihre
Array2D
- Klasse, die C++ - Arrays nicht haben. E. g. in einem 3x2 array, Sie sind in der Lage, Zugriff auf das vierte element in der ersten Zeile, auch wenn es nicht begrifflich gültig. Solche eine häufige Quelle für Fehler können leicht beseitigt werden, indem man ein array-Klasse wie Array2D.Gibt es einige Nachteile, das ist normal bei der Verwendung von Vorlagen. Der big one ist, dass, aufgrund der Art der Vorlage instanziiert sind, müssen Sie zu definieren und vorgefertigte Klassen in Ihren header-Dateien, die nicht in separaten Quelldateien (technisch, können Sie die "export" - Schlüsselwort zu tun, teilen Sie die Klasse als normal, aber dies hat eine begrenzte Unterstützung auf den wichtigsten Compilern).
Als Letzte Anmerkung (wenn es Sie interessiert, wie ich bin), wird die situation noch besser in C++0x (comming soon!) mit dem Aufkommen von variadic templates:
Nun alle array-Typen können definiert werden, indem eine einzelne Klasse Vorlage. Nie war es einfacher.