it-swarm.com.de

Wie finde ich die Länge eines Arrays?

Gibt es eine Möglichkeit, herauszufinden, wie viele Werte ein Array hat? Das Erkennen, ob ich das Ende eines Arrays erreicht habe oder nicht, würde ebenfalls funktionieren.

440
Maxpm

Wenn Sie ein Array im C-Stil meinen, können Sie Folgendes tun:

_int a[7];
std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl;
_

Dies funktioniert jedoch nicht für Zeiger, d. H., Es funktioniert nicht für eine der folgenden Optionen:

_int *p = new int[7];
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
_

oder:

_void func(int *p)
{
    std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
}

int a[7];
func(a);
_

Wenn Sie in C++ diese Art von Verhalten möchten, sollten Sie eine Containerklasse verwenden. wahrscheinlich std::vector .

461

Wie bereits in anderen Worten beschrieben, können Sie die sizeof(arr)/sizeof(*arr) verwenden, dies gibt Ihnen jedoch die falsche Antwort für Zeigertypen, die keine Arrays sind.

template<class T, size_t N>
constexpr size_t size(T (&)[N]) { return N; }

Dies hat die Nice-Eigenschaft, für Nicht-Array-Typen nicht kompiliert zu werden (Visual Studio hat _countof , was dies tut). Die constexpr macht diesen Ausdruck zu einer Kompilierzeit, sodass er keine Nachteile gegenüber dem Makro hat (zumindest keine, die ich kenne).

Sie können auch die Verwendung von std::array aus C++ 11 in Betracht ziehen, das seine Länge ohne zusätzlichen Overhead über ein natives C-Array freigibt.

C++ 17 hat std::size() im <iterator>-Header, der dasselbe tut und auch für STL-Container funktioniert (Dank an @Jon C ).

115
Motti

Mit sizeof( myArray ) erhalten Sie die Gesamtanzahl der für dieses Array zugewiesenen Bytes. Sie können dann die Anzahl der Elemente im Array ermitteln, indem Sie die Größe eines Elements im Array teilen: sizeof( myArray[0] )

73
MahlerFive

Gibt es eine Möglichkeit, herauszufinden, wie viele Werte ein Array hat? 

Ja!

sizeof(array)/sizeof(array[0]) ausprobieren

Das Erkennen, ob ich das Ende eines Arrays erreicht habe oder nicht, würde ebenfalls funktionieren.

Ich sehe keine Möglichkeit dafür, es sei denn, Ihr Array ist ein Array von Zeichen (d. H. String).

P.S: Verwenden Sie in C++ immer std::vector. Es gibt mehrere eingebaute Funktionen und eine erweiterte Funktionalität.

49
Prasoon Saurav

Obwohl dies eine alte Frage ist, lohnt es sich, die Antwort auf C++ 17 zu aktualisieren. In der Standardbibliothek gibt es jetzt die Templated-Funktion std::size() , die die Anzahl der Elemente in einem std-Container oder einem Array im C-Stil zurückgibt. Zum Beispiel:

#include <iterator>

uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4
36
Jon C

std::vector hat eine Methode size(), die die Anzahl der Elemente im Vektor zurückgibt.

(Ja, das ist eine augenzwinkernde Antwort)

25
eq-
#include <iostream>

int main ()
{
    using namespace std;
    int arr[] = {2, 7, 1, 111};
    auto array_length = end(arr) - begin(arr);
    cout << "Length of array: " << array_length << endl;
}
24
JukkaP

Seit C++ 11 werden einige neue Vorlagen eingeführt, die den Umgang mit der Arraylänge erleichtern. Alle sind im Header <type_traits> definiert. 

  • std::rank<T>::value

    Wenn T ein Array-Typ ist, wird der Member-Konstantenwert gleich der Anzahl der Dimensionen des Arrays bereitgestellt. Bei jedem anderen Typ ist der Wert 0.

  • std::extent<T, N>::value

    Wenn T ein Array-Typ ist, wird der Member-Konstantenwert gleich der Anzahl der Elemente entlang der Dimension Nth des Arrays bereitgestellt, wenn N in [0, std::rank<T>::value) ist. Bei jedem anderen Typ oder wenn T ein Array mit unbekannter Grenze entlang der ersten Dimension ist und N 0 ist, ist der Wert 0.

  • std::remove_extent<T>::type

    Wenn T ein Array eines bestimmten Typs ist, X, wird der Typ des Elementtyps gleich X angegeben, andernfalls ist T. Wenn T ein mehrdimensionales Array ist, wird nur die erste Dimension entfernt.

  • std::remove_all_extents<T>::type

    Wenn T ein mehrdimensionales Array eines Typs X ist, wird der Typ typedef type gleich X angegeben, andernfalls ist T.

Um die Länge einer beliebigen Dimension eines multidimentellen Arrays zu ermitteln, kann decltype verwendet werden, um mit std::extent zu kombinieren. Zum Beispiel:

#include <iostream>
#include <type_traits> // std::remove_extent std::remove_all_extents std::rank std::extent

template<class T, size_t N>
constexpr size_t length(T(&)[N]) { return N; }

template<class T, size_t N>
constexpr size_t length2(T(&arr)[N]) { return sizeof(arr) / sizeof(*arr); }

int main()
{
    int a[5][4][3]{{{1,2,3}, {4,5,6}}, { }, {{7,8,9}}};

    // New way
    constexpr auto l1 = std::extent<decltype(a)>::value;     // 5
    constexpr auto l2 = std::extent<decltype(a), 1>::value;  // 4
    constexpr auto l3 = std::extent<decltype(a), 2>::value;  // 3
    constexpr auto l4 = std::extent<decltype(a), 3>::value;  // 0

    // Mixed way
    constexpr auto la = length(a);
    //constexpr auto lpa = length(*a);  // compile error
    //auto lpa = length(*a);  // get at runtime
    std::remove_extent<decltype(a)>::type pa;  // get at compile time
    //std::remove_reference<decltype(*a)>::type pa;  // same as above
    constexpr auto lpa = length(pa);
    std::cout << la << ' ' << lpa << '\n';

    // Old way
    constexpr auto la2 = sizeof(a) / sizeof(*a);
    constexpr auto lpa2 = sizeof(*a) / sizeof(**a);
    std::cout << la2 << ' ' << lpa2 << '\n';

    return 0;
}

BTY, um die Gesamtzahl der Elemente in einem multidimentionalen Array abzurufen:

constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);

Oder legen Sie es in eine Funktionsvorlage:

#include <iostream>
#include <type_traits>
    

template<class T>
constexpr size_t len(T &a)
{
    return sizeof(a) / sizeof(typename std::remove_all_extents<T>::type);
}

int main()
{
    int a[5][4][3]{{{1,2,3}, {4,5,6}}, { }, {{7,8,9}}};
    constexpr auto ttt = len(a);
    int i;
    std::cout << ttt << ' ' << len(i) << '\n';
    
    return 0;
}

Weitere Beispiele zu deren Verwendung finden Sie unter den Links.

21
Jaege

Es gibt auch den TR1/C++ 11/C++ 17-Weg (siehe dort) Live on Colir):

const std::string s[3] = { "1"s, "2"s, "3"s };
constexpr auto n       = std::extent<   decltype(s) >::value; // From <type_traits>
constexpr auto n2      = std::extent_v< decltype(s) >;        // C++17 shorthand

const auto     a    = std::array{ "1"s, "2"s, "3"s };   // C++17 class template arg deduction -- http://en.cppreference.com/w/cpp/language/class_template_argument_deduction
constexpr auto size = std::Tuple_size_v< decltype(a) >;

std::cout << n << " " << n2 << " " << size << "\n"; // Prints 3 3 3
17
metal

Anstatt die eingebaute Array-Funktion zu verwenden,

 int x[2] = {0,1,2};

sie sollten die Array-Klasse und die Array-Vorlage verwenden. Versuchen:

#include <array>
array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {};

wenn Sie also die Länge des Arrays ermitteln möchten, verwenden Sie die Größenfunktion in der Array-Klasse.

Name_of_Array.size();

und das sollte die Länge der Elemente im Array zurückgeben.

9
Mr. Foots

In C++ kann mit der Klasse std :: array ein Array deklariert werden. Die Größe eines Arrays und auch das letzte Element können leicht ermittelt werden.

#include<iostream>
#include<array>
int main()
{
    std::array<int,3> arr;

    //To find the size of the array
    std::cout<<arr.size()<<std::endl;

    //Accessing the last element
    auto it=arr.end();
    std::cout<<arr.back()<<"\t"<<arr[arr.size()-1]<<"\t"<<*(--it);

    return 0;
}

In der Tat hat die Array-Klasse eine ganze Reihe weiterer Funktionen, die es uns ermöglichen, einen Standard-Container zu verwenden.
Referenz 1 zu C++ std :: array class
Referenz 2 zu std :: array class
Die Beispiele in den Referenzen sind hilfreich.

6
Tarun Maganti

Bei C++/CX (beim Schreiben von beispielsweise UWP-Apps mit C++ in Visual Studio) können Sie die Anzahl der Werte in einem Array ermitteln, indem Sie einfach die Funktion size() verwenden.

Quellcode:

string myArray[] = { "Example1", "Example2", "Example3", "Example4" };
int size_of_array=size(myArray);

Wenn Sie cout den size_of_array eingeben, wird folgende Ausgabe ausgegeben:

>>> 4
3
Arslan Ahmad
 length = sizeof(array_name)/sizeof(int);
2
David Gladson

Hier ist eine Implementierung von ArraySize aus Google Protobuf .

#define GOOGLE_ARRAYSIZE(a) \
  ((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))

// test codes...
char* ptr[] = { "you", "are", "here" };
int testarr[] = {1, 2, 3, 4};
cout << GOOGLE_ARRAYSIZE(testarr) << endl;
cout << GOOGLE_ARRAYSIZE(ptr) << endl;

ARRAYSIZE (arr) prüft sizeof (arr) (die Anzahl der Bytes in Des Arrays) und sizeof (* (arr)) (die Anzahl der Bytes in einem Array Element). Wenn Ersteres durch Letzteres teilbar ist, ist Arr vielleicht in der Tat ein Array, in welchem ​​Fall das Ergebnis der Division die # von .__ ist. Elemente im Array. Andernfalls kann arr möglicherweise kein Array sein und wir generieren einen Compiler-Fehler, um den Code von .__ zu verhindern. kompilieren.

Da die Größe von bool implementierungsdefiniert ist, müssen wir .__ umwandeln. ! (sizeof (a) & sizeof (* (a))) bis size_t, um das endgültige .__ sicherzustellen. Ergebnis hat den Typ size_t.

Dieses Makro ist nicht perfekt, da es bestimmte .__ falsch akzeptiert. Zeiger, nämlich wenn die Zeigergröße durch den Pointee teilbar ist Größe. Da unser gesamter Code einen 32-Bit-Compiler durchlaufen muss, muss Wenn ein Zeiger 4 Byte ist, bedeutet dies alle Zeiger auf einen Typ, dessen Größe 3 oder größer als 4 wird (richtig) abgelehnt.

2
zangw

Eine gute Lösung, die Generika verwendet:

template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }

Rufen Sie dann einfach arraysize(_Array); auf, um die Länge des Arrays zu ermitteln.

Quelle

Für alte g ++ - Compiler können Sie dies tun

template <class T, size_t N>
char (&helper(T (&)[N]))[N];

#define arraysize(array) (sizeof(helper(array)))

int main() {
    int a[10];
    std::cout << arraysize(a) << std::endl;
    return 0;
}
1
Scy

Ich biete hier eine knifflige Lösung: 

Sie können length immer im ersten Element speichern:

// malloc/new

arr[0] = length;
arr++;

// do anything. 
int len = *(arr-1);

free(--arr); 

Die Kosten betragen --arr, wenn free aufgerufen wird

1
陳 力

Verwenden Sie den Typ nicht zusammen mit sizeof, da sizeof(array)/sizeof(char) plötzlich beschädigt wird, wenn Sie den Typ des Arrays ändern.

In Visual Studio haben Sie das Äquivalent, wenn sizeof(array)/sizeof(*array). Sie können einfach _countof(array) eingeben.

0
Johan Jönsson

Ich persönlich würde vorschlagen (wenn Sie aus irgendeinem Grund nicht in der Lage sind, mit speziellen Funktionen zu arbeiten), zuerst die Array-Typ-Kompatibilität über das zu erweitern, was Sie normalerweise verwenden würden (wenn Sie Werte ≥ 0 speichern würden):

unsigned int x[] -> int x[]

als würden Sie das Array 1-Element größer machen, als Sie brauchen, um es zu machen. Für das letzte Element würden Sie einen Typ angeben, der im erweiterten Typbezeichner enthalten ist, den Sie jedoch normalerweise nicht verwenden würden, z. im vorigen Beispiel wäre das letzte Element -1. Auf diese Weise können Sie (mithilfe einer for-Schleife) das letzte Element eines Arrays finden.

0

sie können die Länge eines Arrays wie folgt ermitteln:

int  arr[] = {1, 2, 3, 4, 5, 6}; 
int size = *(&arr + 1) - arr; 
cout << "Number of elements in arr[] is "<< size; 
return 0;
0

Sie können dieses Snippet einfach verwenden:

#include <iostream>
#include <string>
#include <array>

using namespace std;

int main()
{

  array<int,3> values;
  cout << "No. elements in valuea array: " << values.size() << " elements." << endl;
  cout << "sizeof(myints): " << sizeof(values) << endl;

}

und hier ist die Referenz: http://www.cplusplus.com/reference/array/array/size/

0
Amado Saladino

Sie haben eine Reihe von Optionen, mit denen Sie die Größe eines C-Arrays ermitteln können.

int myArray [] = {0, 1, 2, 3, 4, 5, 7};

1) sizeof(<array>) / sizeof(<type>):

std::cout << "Size:" << sizeof(myArray) / sizeof(int) << std::endl;

2) sizeof(<array>) / sizeof(*<array>):

std::cout << "Size:" << sizeof(myArray) / sizeof(*myArray) << std::endl;

3) sizeof(<array>) / sizeof(<array>[<element>]):

std::cout << "Size:" << sizeof(myArray) / sizeof(myArray[0]) << std::endl;
0
Ito

Nur ein Gedanke, aber gerade beschlossen, eine Zählervariable zu erstellen und die Arraygröße in Position [0] zu speichern. Ich habe den größten Teil des Codes gelöscht, den ich in der Funktion hatte, aber nach dem Verlassen der Schleife wird angezeigt, dass prime [0] den endgültigen Wert von 'a' zugewiesen hat. Ich habe es mit Vektoren versucht, aber VS Express 2013 hat das nicht sehr gefallen. Beachten Sie auch, dass 'a' bei Eins anfängt, um das Überschreiben von [0] zu vermeiden, und es wird am Anfang initialisiert, um Fehler zu vermeiden. Ich bin kein Experte, dachte nur, ich würde es teilen. 

int prime[] = {0};
int primes(int x, int y){
    using namespace std; int a = 1;
    for (int i = x; i <= y; i++){prime[a] = i; a++; }
    prime[0] = a; return 0;
}
0
Das_Newb

Einer der häufigsten Gründe, warum Sie danach suchen würden, ist, dass Sie ein Array an eine Funktion übergeben möchten und kein anderes Argument für die Größe übergeben müssen. Im Allgemeinen möchten Sie auch, dass die Arraygröße dynamisch ist. Dieses Array kann Objekte enthalten, keine Grundelemente, und die Objekte können komplex sein, so dass size_of () eine nicht sichere Option zum Berechnen der Anzahl ist. 

Wie andere vorgeschlagen haben, sollten Sie die Verwendung eines std :: -Vektors oder einer Liste usw. anstelle eines primitiven Arrays in Betracht ziehen. Bei alten Compilern haben Sie jedoch immer noch nicht die endgültige Lösung, die Sie wahrscheinlich möchten, da das Auffüllen des Containers eine Reihe hässlicher Push_back () - Zeilen erfordert. Wenn Sie wie ich sind, möchten Sie eine einzeilige Lösung mit anonymen Objekten.

Wenn Sie die STL-Container-Alternative zu einem primitiven Array verwenden, kann dieser SO -Posten für die Initialisierung hilfreich sein: Was ist der einfachste Weg, einen std :: vector mit hardcoded zu initialisieren Elemente?

Hier ist eine Methode, die ich dafür verwende, die universell über Compiler und Plattformen hinweg funktioniert:

Erstellen Sie eine Struktur oder Klasse als Container für Ihre Sammlung von Objekten. Definieren Sie eine Operatorüberlastungsfunktion für <<.

class MyObject;

struct MyObjectList
{
    std::list<MyObject> objects;
    MyObjectList& operator<<( const MyObject o )
    { 
        objects.Push_back( o );
        return *this; 
    }
};

Sie können Funktionen erstellen, die Ihre Struktur als Parameter verwenden, z. 

someFunc( MyObjectList &objects );

Dann können Sie diese Funktion wie folgt aufrufen:

someFunc( MyObjectList() << MyObject(1) <<  MyObject(2) <<  MyObject(3) );

Auf diese Weise können Sie eine dynamisch große Objektkollektion erstellen und an eine Funktion in einer einzigen klaren Linie übergeben.

0
BuvinJ