Wie ermittle ich die Größe meines Arrays in C?

Wie ermittle ich die Größe meines Arrays in C?

Das heißt, die Anzahl der Elemente, die das Array enthalten kann?

Zusammenfassung:

int a[17]; size_t n = sizeof(a)/sizeof(a[0]); 

Um die Größe Ihres Arrays in Bytes zu bestimmen, können Sie den Operator sizeof :

 int a[17]; size_t n = sizeof(a); 

Auf meinem Computer sind Ints 4 Bytes lang, also ist n 68.

Um die Anzahl der Elemente im Array zu bestimmen, können wir die Gesamtgröße des Arrays durch die Größe des Array-Elements teilen. Du könntest das mit dem Typ machen, so:

 int a[17]; size_t n = sizeof(a) / sizeof(int); 

und erhalten die richtige Antwort (68/4 = 17), aber wenn der Typ a Änderung Sie hätten einen bösen Fehler, wenn Sie vergessen hätten, die sizeof(int) auch zu ändern.

Der bevorzugte Teiler ist also sizeof(a[0]) , die Größe des nullten Elements des Arrays.

 int a[17]; size_t n = sizeof(a) / sizeof(a[0]); 

Ein weiterer Vorteil ist, dass Sie jetzt den Array-Namen in einem Makro einfach parametrisieren können und erhalten:

 #define NELEMS(x) (sizeof(x) / sizeof((x)[0])) int a[17]; size_t n = NELEMS(a); 

Der Weg ist der richtige Weg, wenn Sie mit Arrays arbeiten, die nicht als Parameter empfangen werden. Ein Array, das als Parameter an eine function gesendet wird, wird als pointers behandelt, sodass sizeof die Größe des pointerss anstelle der des Arrays zurückgibt.

Insofern funktioniert diese Methode nicht. size_t size stattdessen immer einen zusätzlichen Parameter size_t size , der die Anzahl der Elemente im Array angibt.

Prüfung:

 #include  #include  void printSizeOf(int intArray[]); void printLength(int intArray[]); int main(int argc, char* argv[]) { int array[] = { 0, 1, 2, 3, 4, 5, 6 }; printf("sizeof of array: %d\n", (int) sizeof(array)); printSizeOf(array); printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) )); printLength(array); } void printSizeOf(int intArray[]) { printf("sizeof of parameter: %d\n", (int) sizeof(intArray)); } void printLength(int intArray[]) { printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) )); } 

Ausgabe (in einem 64-Bit Linux OS):

 sizeof of array: 28 sizeof of parameter: 8 Length of array: 7 Length of parameter: 2 

Ausgabe (in einem 32-Bit-Windows-Betriebssystem):

 sizeof of array: 28 sizeof of parameter: 4 Length of array: 7 Length of parameter: 1 

Es ist erwähnenswert, dass sizeof nicht hilft, wenn man mit einem Array-Wert arbeitet, der zu einem pointers verfallen ist: Obwohl er auf den Anfang eines Arrays zeigt, ist er für den Compiler dasselbe wie ein pointers auf ein einzelnes Element davon Array. Ein pointers “erinnert” sich an nichts anderes über das Array, mit dem es initialisiert wurde.

 int a[10]; int* p = a; assert(sizeof(a) / sizeof(a[0]) == 10); assert(sizeof(p) == sizeof(int*)); assert(sizeof(*p) == sizeof(int)); 

Die Größe von “Trick” ist der beste Weg, ich weiß, mit einem kleinen, aber (für mich, das ist ein großes Haustier ärgern) wichtige Änderung in der Verwendung von Klammern.

Wie der Wikipedia-Eintrag verdeutlicht, ist sizeof keine function; es ist ein Operator . Daher ist keine Klammer um das Argument erforderlich, es sei denn, das Argument ist ein Typname. Dies ist leicht zu merken, da das Argument wie ein Cast-Ausdruck aussieht, der auch Klammern verwendet.

Also: Wenn du folgendes hast:

 int myArray[10]; 

Sie können die Anzahl der Elemente mit folgendem Code finden:

 size_t n = sizeof myArray / sizeof *myArray; 

Das liest sich für mich viel einfacher als die Alternative mit Klammern. Ich bevorzuge auch die Verwendung des Sternchens im rechten Teil der Abteilung, da es prägnanter ist als die Indexierung.

Natürlich ist dies auch die Kompilierzeit, so dass Sie sich keine Gedanken über die Aufteilung machen müssen, die die performance des Programms beeinträchtigt. Verwenden Sie diese Form also wo immer Sie können.

Es ist immer am besten, sizeof für ein tatsächliches Objekt zu verwenden, wenn Sie eines haben, und nicht für einen Typ, da Sie sich dann keine Sorgen machen müssen, einen Fehler zu machen und den falschen Typ anzugeben.

Angenommen, Sie haben eine function, die einige Daten als Datenstrom ausgibt, z. B. über ein Netzwerk. Lassen Sie uns die function send() aufrufen und sie als Argument einen pointers auf das zu sendende Objekt und die Anzahl der Bytes im Objekt nehmen lassen. Also, der Prototyp wird:

 void send(const void *object, size_t size); 

Und dann müssen Sie eine Ganzzahl senden, also schreiben Sie es so:

 int foo = 4711; send(&foo, sizeof (int)); 

Jetzt haben Sie eine subtile Art und Weise eingeführt, sich selbst in den Fuß zu schießen, indem Sie den Typ von foo an zwei Stellen foo . Wenn sich einer ändert, aber der andere nicht, bricht der Code. Also mach es immer so:

 send(&foo, sizeof foo); 

Jetzt bist du geschützt. Sicher, du duplizierst den Namen der Variablen, aber das hat eine hohe Wahrscheinlichkeit zu brechen, wie der Compiler erkennen kann, wenn du es änderst.

 int size = (&arr)[1] - arr; 

Sehen Sie sich diesen Link für eine Erklärung an

Sie können den Operator sizeof verwenden, aber er funktioniert nicht für functionen, da er die Referenz des pointerss benötigt, um die Länge eines Arrays zu ermitteln:

 len = sizeof(arr)/sizeof(arr[0]) 

Code ursprünglich hier gefunden: C-Programm, um die Anzahl der Elemente in einem Array zu finden

Wenn Sie den Datentyp des Arrays kennen, können Sie Folgendes verwenden:

 int arr[] = {23, 12, 423, 43, 21, 43, 65, 76, 22}; int noofele = sizeof(arr)/sizeof(int); 

Oder wenn Sie den Datentyp des Arrays nicht kennen, können Sie Folgendes verwenden:

 noofele = sizeof(arr)/sizeof(arr[0]); 

Hinweis: Diese function funktioniert nur, wenn das Array zur Laufzeit nicht definiert ist (wie malloc) und das Array in einer function nicht übergeben wird. In beiden Fällen ist arr (Array-Name) ein pointers.

Das Makro ARRAYELEMENTCOUNT(x) , das von allen verwendet wird, wird falsch ausgewertet. Dies ist realistisch gesehen nur eine heikle Angelegenheit, da Sie keine Ausdrücke haben können, die zu einem Array-Typ führen.

 /* Compile as: CL /P "macro.c" */ # define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x[0])) ARRAYELEMENTCOUNT(p + 1); 

Eigentlich bewertet als:

 (sizeof (p + 1) / sizeof (p + 1[0])); 

Wohingegen

 /* Compile as: CL /P "macro.c" */ # define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x)[0]) ARRAYELEMENTCOUNT(p + 1); 

Es bewertet korrekt zu:

 (sizeof (p + 1) / sizeof (p + 1)[0]); 

Das hat wirklich nicht viel mit der Größe von Arrays zu tun. Ich habe gerade eine Menge Fehler bemerkt, weil ich nicht wirklich beobachtet habe, wie der C-Präprozessor funktioniert. Sie wickeln immer den Makroparameter um, nicht ein Ausdruck, an dem möglicherweise beteiligt ist.


Das ist richtig; mein Beispiel war schlecht. Aber genau das sollte eigentlich passieren. Wie ich bereits erwähnt habe, wird p + 1 pointerstyp enden und das gesamte Makro ungültig machen (genau wie wenn Sie versucht hätten, das Makro in einer function mit einem pointersparameter zu verwenden).

Am Ende des Tages, in diesem speziellen Fall, ist der Fehler nicht wirklich wichtig (so verschwende ich nur die Zeit aller, Huzzah!), Weil Sie keine Ausdrücke mit einer Art von ‘Array’ haben. Aber tatsächlich ist der Punkt über die Präprozessor-Bewertung subtil, denke ich, ist ein wichtiger.

Bei mehrdimensionalen Arrays ist es etwas komplizierter. Häufig definieren Leute explizite Makrokonstanten, dh

 #define g_rgDialogRows 2 #define g_rgDialogCols 7 static char const* g_rgDialog[g_rgDialogRows][g_rgDialogCols] = { { " ", " ", " ", " 494", " 210", " Generic Sample Dialog", " " }, { " 1", " 330", " 174", " 88", " ", " OK", " " }, }; 

Diese Konstanten können aber auch zur Kompilierungszeit mit sizeof ausgewertet werden:

 #define rows_of_array(name) \ (sizeof(name ) / sizeof(name[0][0]) / columns_of_array(name)) #define columns_of_array(name) \ (sizeof(name[0]) / sizeof(name[0][0])) static char* g_rgDialog[][7] = { /* ... */ }; assert( rows_of_array(g_rgDialog) == 2); assert(columns_of_array(g_rgDialog) == 7); 

Beachten Sie, dass dieser Code in C und C ++ funktioniert. Verwenden Sie Arrays mit mehr als zwei Dimensionen

 sizeof(name[0][0][0]) sizeof(name[0][0][0][0]) 

usw., ad infinitum.

Größe eines Arrays in C:

 int a[10]; size_t size_of_array = sizeof(a); // Size of array a int n = sizeof (a) / sizeof (a[0]); // Number of elements in array a size_t size_of_element = sizeof(a[0]); // Size of each element in array a // Size of each element = size of type 
 sizeof(array) / sizeof(array[0]) 
 #define SIZE_OF_ARRAY(_array) (sizeof(_array) / sizeof(_array[0])) 

“Sie haben eine subtile Art und Weise eingeführt, sich selbst in den Fuß zu schießen”

C ‘native’ Arrays speichern ihre Größe nicht. Es wird daher empfohlen, die Länge des Arrays in einer separaten Variablen / const zu speichern und sie beim Übergeben des Arrays zu übergeben, das heißt:

 #define MY_ARRAY_LENGTH 15 int myArray[MY_ARRAY_LENGTH]; 

Sie sollten immer native Arrays vermeiden (es sei denn, Sie können nicht, in diesem Fall, Ihren Fuß kümmern). Wenn Sie C ++ schreiben, verwenden Sie den Vektor Container der STL . “Im Vergleich zu Arrays bieten sie fast die gleiche performance”, und sie sind viel nützlicher!

 // vector is a template, the  means it is a vector of ints vector numbers; // push_back() puts a new value at the end (or back) of the vector for (int i = 0; i < 10; i++) numbers.push_back(i); // Determine the size of the array cout << numbers.size(); 

Siehe: http://www.cplusplus.com/reference/stl/vector/

@ Magnus: Der Standard definiert sizeof als die Anzahl der Bytes im Objekt und die Größe von (char) ist immer eins. Die Anzahl der Bits in einem Byte ist implementierungsspezifisch.

Bearbeiten: ANSI C ++ Standard Abschnitt 5.3.3 Größe von:

Der Operator sizeof liefert die Anzahl der Bytes in der Objektdarstellung seines Operanden. […] sizeof (char), sizeof (signiertes Zeichen) und sizeof (vorzeichenloses Zeichen) sind 1; Das Ergebnis von sizeof, das auf einen anderen fundamentalen Typ angewendet wird, ist implementierungsdefiniert.

Abschnitt 1.6 Das C ++ Speichermodell:

Die grundlegende Speichereinheit im C ++ – Speichermodell ist das Byte. Ein Byte ist mindestens groß genug, um ein beliebiges Element des grundlegenden Ausführungszeichensatzes aufzunehmen, und besteht aus einer zusammenhängenden Sequenz von Bits, deren Anzahl implementierungsdefiniert ist.

@Skizz: Ich bin mir ziemlich sicher, dass ich recht habe, obwohl die beste “Quelle”, die ich dir im Moment geben kann, Wikipedia ist, aus dem Artikel über sizeof:

Wikipedia ist falsch, Skizz hat Recht. sizeof (char) ist per definitionem 1.

Ich meine, lies den Wikipedia-Eintrag wirklich genau, um zu sehen, dass es falsch ist. “Vielfache von Char”. sizeof(char) kann niemals etwas anderes als “1” sein. Wenn es beispielsweise 2 wäre, würde dies bedeuten, dass die Größe von sizeof(char) doppelt so groß ist wie die von char!

Wenn Sie dies wirklich tun wollen, um Ihr Array zu umgehen, empfehle ich, eine Struktur zu implementieren, um einen pointers auf den Typ zu speichern, den Sie für ein Array und eine Ganzzahl haben möchten, die die Größe des Arrays repräsentiert. Dann können Sie das an Ihre functionen weitergeben. Ordnen Sie diesem pointers einfach den Array-Variablenwert (pointers auf das erste Element) zu. Dann können Sie Array.arr[i] , um das i-te Element zu erhalten und Array.size , um die Anzahl der Elemente im Array zu ermitteln.

Ich habe einen Code für dich eingefügt. Es ist nicht sehr nützlich, aber Sie könnten es mit mehr functionen erweitern. Um ehrlich zu sein, sollten Sie jedoch aufhören, C zu verwenden und eine andere Sprache mit diesen integrierten functionen zu verwenden.

 /* Absolutely no one should use this... By the time you're done implementing it you'll wish you just passed around an array and size to your functions */ /* This is a static implementation. You can get a dynamic implementation and cut out the array in main by using the stdlib memory allocation methods, but it will work much slower since it will store your array on the heap */ #include  #include  /* #include "MyTypeArray.h" */ /* MyTypeArray.h #ifndef MYTYPE_ARRAY #define MYTYPE_ARRAY */ typedef struct MyType { int age; char name[20]; } MyType; typedef struct MyTypeArray { int size; MyType *arr; } MyTypeArray; MyType new_MyType(int age, char *name); MyTypeArray newMyTypeArray(int size, MyType *first); /* #endif End MyTypeArray.h */ /* MyTypeArray.c */ MyType new_MyType(int age, char *name) { MyType d; d.age = age; strcpy(d.name, name); return d; } MyTypeArray new_MyTypeArray(int size, MyType *first) { MyTypeArray d; d.size = size; d.arr = first; return d; } /* End MyTypeArray.c */ void print_MyType_names(MyTypeArray d) { int i; for (i = 0; i < d.size; i++) { printf("Name: %s, Age: %d\n", d.arr[i].name, d.arr[i].age); } } int main() { /* First create an array on the stack to store our elements in. Note we could create an empty array with a size instead and set the elements later. */ MyType arr[] = {new_MyType(10, "Sam"), new_MyType(3, "Baxter")}; /* Now create a "MyTypeArray" which will use the array we just created internally. Really it will just store the value of the pointer "arr". Here we are manually setting the size. You can use the sizeof trick here instead if you're sure it will work with your compiler. */ MyTypeArray array = new_MyTypeArray(2, arr); /* MyTypeArray array = new_MyTypeArray(sizeof(arr)/sizeof(arr[0]), arr); */ print_MyType_names(array); return 0; } 

Am besten speichern Sie diese Informationen beispielsweise in einer Struktur:

 typedef struct { int *array; int elements; } list_s; 

Implementieren Sie alle notwendigen functionen wie Erstellen, Löschen, Überprüfen der Gleichheit und alles, was Sie sonst noch brauchen. Es ist einfacher, als Parameter zu übergeben.

Sie können den Operator & . Hier ist der Quellcode:

 #include #include int main(){ int a[10]; int *p; printf("%p\n", (void *)a); printf("%p\n", (void *)(&a+1)); printf("---- diff----\n"); printf("%zu\n", sizeof(a[0])); printf("The size of array a is %zu\n", ((char *)(&a+1)-(char *)a)/(sizeof(a[0]))); return 0; }; 

Hier ist die Beispielausgabe

 1549216672 1549216712 ---- diff---- 4 The size of array a is 10 

Die function sizeof gibt die Anzahl der Bytes zurück, die von Ihrem Array im Speicher verwendet werden. Wenn Sie die Anzahl der Elemente in Ihrem Array berechnen möchten, teilen Sie diese Zahl mit der sizeof Variablentyps des Arrays. Nehmen wir an, das int array[10]; Wenn der Integer vom Typ Variable in Ihrem Computer 32 Bit (oder 4 Byte) ist, sollten Sie Folgendes tun, um die Größe Ihres Arrays zu erhalten:

 int array[10]; int sizeOfArray = sizeof(array)/sizeof(int); 
 int a[10]; int size = (*(&a+1)-a) ; 

für weitere Informationen: https://aticleworld.com/how-find-sizeof-array-in-c-c-withousout-sizeof/ https://www.geeksforgeeks.org/how-to-find-size- of-array-in-cc-ohne-using-sizeof-operator /

Benutzen:

 int a=[10] = {1, 2, 3, 4, 5}; int n = sizeof(a); printf("%d", n); 

Ausgabe:

 5 

Grund: Berechnet die Anzahl der im Array enthaltenen Elemente und nicht die Anzahl der zugewiesenen freien Plätze.