Kann ich bestimmen die Größe/Länge eines Arrays in C++ die zimmerreserviereung, ohne das hartcodieren?
Ich bin im Grunde auf der Suche nach einer Art "dynamischen" Weg der Größe/Länge eines Arrays an eine Funktion.
Habe ich versucht:
void printArray(int arrayName[])
{
for(int i = 0 ; i < sizeof(arrayName); ++i)
{
cout << arrayName[i] << ' ';
}
}
Aber ich erkannte, dass es nur der Auffassung Ihrer Bytegröße und nicht, wie viele Elemente im array.
Und auch:
void printArray(int *arrayName)
{
while (*arrayName)
{
cout << *arrayName << ' ';
*arrayName++;
}
}
Dieser hat zumindest mir alles, was gedruckt, aber mehr als das, was ich erwartet hatte, so dass es nicht wirklich funktionieren, wie ich es mir vorstelle.
Ich denke, es ist weil ich nicht genau sagen, wie groß ich brauche es so ist, spielt es "sicher" und wirft mir einige große Größe und schließlich beginnt mit dem drucken mich sehr ungeraden zahlen nach meinem letzten element im array.
So, ich habe endlich dieses umgehen, doch glaube ich, dass es etwas besseres gibt!:
void printArray(int *arrayName)
{
while (*arrayName)
{
if (*arrayName == -858993460)
{
break;
}
cout << *arrayName << ' ';
*arrayName++;
}
cout << '\n';
}
Nach läuft das Programm ein paar mal erkannte ich den Wert nach dem letzten element des Arrays, dass ich input ist immer: -858993460, also machte ich es brechen die while-Schleife ab, sobald dieser Wert festgestellt wird.
include <iostream>
include <conio.h>
using namespace std;
//functions prototypes
void printArray (int arrayName[], int lengthArray);
//global variables
//main
int main ()
{
int firstArray[] = {5, 10, 15};
int secondArray[] = {2, 4, 6, 8, 10};
printArray (firstArray,3);
printArray (secondArray,5);
//end of program
_getch();
return 0;
}
//functions definitions
void printArray(int arrayName[], int lengthArray)
{
for (int i=0; i<lengthArray; i++)
{
cout << arrayName[i] << " ";
}
cout << "\n";
}
Danke Ihnen sehr.
- Dein grundlegendes Missverständnis ist, dass die Funktion erhält ein array, wenn in Wirklichkeit, es erhält einen Zeiger. Arrays übergeben werden können, um Funktionen (oder zurück von Ihnen). Bauen Sie auf Zeiger.
- Ich denke ich bekomme es. Also, wenn ich ein array erstellen, das ist eine Ansiedlung irgendwo in den Speicher. Wenn ich will, zu "benutzen", das array, um es zu übergeben, um eine Funktion, ich bin tatsächlich an der Funktion eine Adresse, wo dieses array kann man in der Erinnerung, die von sich selbst weit überlegene Speicher-Weise, als wäre es die übergabe eines tatsächlichen array?
Du musst angemeldet sein, um einen Kommentar abzugeben.
1st try
Wenn arrays an Funktionen übergeben werden, Sie zerfallen zu Zeigern. Normalerweise, mit
sizeof
auf ein array geben würde Sie Ihre Größe in bytes, die könnte man dann geteilt durch die Größe in bytes der einzelnen Elemente und erhalten die Anzahl der Elemente. Aber jetzt, da du einen pointer statt einem array aufrufensizeof
nur gibt Sie die Größe des Mauszeigers (in der Regel 4 oder 8 bytes), nicht das array selbst und das ist, warum dies nicht gelingt.2. Versuch
Die while-Schleife in diesem Beispiel wird davon ausgegangen, dass das array endet mit einer null, und das ist sehr schlecht (es sei denn, man hat wirklich verwenden Sie eine null als terminator wie null-terminierte strings zum Beispiel). Wenn dein array nicht mit null enden, könnten Sie den Zugriff auf Speicher, die nicht verkaufen und daher aufrufen zu undefiniertem Verhalten. Eine andere Sache, die passieren könnte, ist, dass dein array hat eine null-element in der Mitte würde dann nur drucken, die ersten paar Elemente.
3. versuchen Sie,
Dieser Besondere Wert, den Sie gefunden lauern am Ende der Arrays jederzeit ändern können. Dieser Wert war nur zufällig dort an diesem Punkt, und es könnte anders sein, ein anderes mal so hardcoding es ist sehr gefährlich, denn Sie könnte end up Zugriff auf Speicher, die nicht verkaufen.
Ihre endgültige code -
Dieser code ist korrekt, und übergeben Sie die Länge des Arrays zusammen mit dem array selbst ist etwas, was Häufig getan (vor allem in den APIs in C geschrieben). Dieser code sollte keine Probleme verursachen, solange Sie sich nicht über eine Länge, die größer als die tatsächliche Länge des Arrays, und dies kann manchmal passieren so ist es auch fehleranfällig.
Eine andere Lösung
Andere Lösung wäre die Verwendung
std::vector
einem Behälter, die zusammen mit verfolgen, von Ihrer Größe, können Sie auch hinzufügen, wie viele Elemente, wie Sie wollen, d.h. die Größe muss nicht bekannt sein, zur Laufzeit. So konnte man etwas wie das hier tun:Nützliche links lohnt sich
Undefiniertes Verhalten: Undefinierten, unbestimmten und Implementierung-definiert das Verhalten
Array decay: Was ist array verfallenden?
std::vector: http://en.cppreference.com/w/cpp/container/vector
TL;DR-Antwort: verwenden Sie
std::vector
.Wäre das nicht ein problem in sich: Sie könnten sich trotzdem die Größe des Arrays mit
sizeof(array) /sizeof(array[0])
, aber das problem ist, dass, wenn an eine Funktion übergeben, arrays Zerfall in einen Zeiger auf Ihr erstes element, so dass alle Sie bekommen könnensizeof(T *)
(T ist dabei der Typ eines Elements im array).Über
*arrayName++
:Ich gar nicht verstehen, was hat Sie dazu inspiriert, berechnen Sie die Größe des array in dieser Art und Weise. Alles, was dieser code tut, ist die Inkrementierung der das erste Objekt in das array, bis es null.
Das ist eine schreckliche Annahme, und es stützt sich auch auf nicht definiertes Verhalten. Sie können nicht wirklich sicher sein, was in der Erinnerung nach das erste element des array, sollten Sie nicht selbst Zugriff darauf haben.
Grundsätzlich in C++, wenn Sie wollen, um zu wissen, die Größe einer raw-array innerhalb einer Funktion, dann musst du den überblick behalten manuell (e. g. hinzufügen eines zusätzlichen
size_t size
argument), weil der Weg arrays werden an Funktionen übergeben (Sie erinnern sich, "Zerfall in ein" Zeiger). Wenn Sie etwas flexibler sind, sollten Sie die Verwendungstd::vector<int>
(oder was auch immer Art von Objekten, die Sie speichern möchten) aus der C++ standard Bibliothek-es hat einesize()
Methode, die genau das tut, was Sie wollen.sizeof
ist nicht eine Funktion.but the problem is that when passed to a function, arrays decay into a pointer to their first element, so all you can get is sizeof(T *)
, wasT[]
zerfällt, wenn an diesizeof
"Funktion".sizeof
Werke auf diesen Zeiger.sizeof()
funktioniert einwandfrei auf array nur, bevor Sie an die Funktion übergeben. In der Funktion, die Sie nicht haben eine Reihe mehr).Als all die anderen Antworten sagen, sollten Sie
std::vector
oder, als Sie bereits haben, übergeben Sie die Anzahl der Elemente des Arrays, um die drucken-Funktion.Einen anderen Weg, dies zu tun ist, indem Sie ein sentinel-element (ein Wert, den Sie sind sicher, es wird nicht im array) an das Ende des Arrays. In der Druck-Funktion Sie können mit dem Rad dann durch die Elemente, und wenn Sie den sentinel-Sie stoppen.
std::vector
ist wahrscheinlich der bessere Ansatz ist, und die, die Sie berücksichtigen sollten, bevor irgendetwas anderes beim Umgang mit dynamisch dimensionierte arrays.Eine mögliche Lösung: Sie können eine Vorlage verwenden, um Rückschlüsse auf die array-Länge:
Beachten Sie, dass Sie haben, dies zu tun vor das array zerfällt zu einem Zeiger, aber Sie können die Technik direkt oder in einem wrapper.
Zum Beispiel, wenn Sie nichts dagegen haben, Ihre eigenen Rollen-array-wrapper:
Können Sie dies tun:
- und nennen es wie
Der Schlüssel ist, dass die Vorlagen-Konstruktor ist nicht
explicit
also dein array umgewandelt werden können, um eine Instanz, die Erfassung der Größe, vor verfallenden einem Zeiger.NB. Der wrapper gezeigt, ist nicht geeignet für den Besitz und dynamisch-sized arrays, nur für den Umgang mit statisch dimensionierten arrays bequem. Es fehlen auch verschiedene Operatoren und ein Standard-Konstruktor, der Kürze halber. Im Allgemeinen bevorzugen
std::vector
oderstd::array
statt für den Allgemeinen Gebrauch.... OP ' s eigene versuche sind komplett an eine andere Stelle adressiert ...
Mithilfe der -858993460 Wert ist höchst unzuverlässig und, in der Tat falsch.
Können Sie ein Länge des Arrays in zwei Möglichkeiten: übergeben wird ein zusätzlicher parameter (sagen
size_t length
) an Ihre Funktion, oder legen einen besonderen Wert an das Ende von array. Der erste Weg ist vorzuziehen, aber die zweite wird verwendet, zum Beispiel für die übergabe von strings durch char*.In C/C++ ist es nicht möglich, zu wissen, die Größe eines Arrays zur Laufzeit. Sie könnte erwägen, einen
std::vector
Klasse, wenn Sie das brauchen, und es hat auch andere Vorteile.sizeof(some_array) / sizeof(some_array[0])
gibt die Größe eines Arrays. Die OP ' s problem ist, dass er denkt, er hat ein array, wenn er tatsächlich ein Zeiger.sizeof
ist eine compile-Zeit-Berechnung, und die arrays nicht abgeschätzt werden kann, zur Laufzeit. Also ich glaube, ich sollte gesagt haben, irreführend statt. Die Antwort ist nicht hilfreich aber. Die OP braucht, um zu verstehen, wenn ein array ist ein array und wenn es ein Zeiger in der Verkleidung (wie im Beispiel)Wenn Sie übergeben Sie die Länge des Arrays zu
printArray
verwenden, können Siesizeof(array) /sizeof(array[0])
, das heißt die Größe in bytes) des gesamten Arrays dividiert durch die Größe in Byte für ein einzelnes element gibt man die Größe in Elemente des array selbst.Mehr auf den Punkt, in C++ können Sie finden es zu Ihrem Vorteil, zu lernen, über
std::vector
undstd::array
und bevorzugen diese über raw-arrays—es sei denn natürlich du machst eine Hausaufgabe, die erfordert, dass Sie lernen, über die raw-arrays. Diesize()
member-Funktion geben Sie die Anzahl der Elemente in einem Vektor.sizeof
Werte. Ohne allzu sehr ins detail, wird ein Zeiger in der Regel 4 Byte auf einem 32-bit system und 8 Byte auf einem 64-bit-system. Sie würde sehen, das Ergebnis, dass der Wert geteilt durchsizeof(int)
.In C/C++, native arrays abbauen Zeiger, sobald Sie an Funktionen übergeben werden. Als solche, die "length" - parameter übergeben werden, als parameter für die Funktion.
C++ bietet die std::vector collection-Klasse. Stellen Sie sicher, dass, wenn Sie übergeben es an eine Funktion übergeben Sie es als Referenz oder als Zeiger (um zu vermeiden, dass eine Kopie des Arrays, wie es übergeben wird).