Wie bestimme ich die Größe meines Arrays in C?
Das heißt, die Anzahl der Elemente, die das Array aufnehmen kann?
Wie bestimme ich die Größe meines Arrays in C?
Das heißt, die Anzahl der Elemente, die das Array aufnehmen kann?
int size = (&arr)[1] - arr;
Überprüfen Sie dieser Link zur Erläuterung
Kleines Manko: Das Ergebnis der Zeigersubtraktion hat den Typ ptrdiff_t
. (Auf 64-Bit-Systemen ist dies in der Regel ein größerer Typ als int
). Auch wenn Sie die int
a ptrdiff_t
in diesem Code, hat es immer noch einen Fehler, wenn arr
mehr als die Hälfte des Adressraums beansprucht.
@M.M Ein weiterer kleiner Kritikpunkt: Je nach Systemarchitektur ist der Adressraum auf den meisten Systemen nicht annähernd so groß wie die Zeigergröße. Windows zum Beispiel begrenzt den Adressraum für 64-Bit-Anwendungen auf 8 TB oder 44 Bit. Selbst wenn Sie also ein Array haben, das größer ist als die Hälfte Ihres Adressraums, z. B. 4,1 TB, stellt dies keinen Fehler dar. Nur wenn Ihr Adressraum auf diesen Systemen 63 Bit überschreitet, ist es möglich, dass ein solcher Fehler auftritt. Im Allgemeinen sollten Sie sich keine Sorgen machen.
@Aidiakapi auf 32-bit x86 Linux oder auf Windows mit /3G
Option haben Sie eine 3G/1G Benutzer/Kernel-Aufteilung, die es Ihnen ermöglicht, Arrays mit einer Größe von bis zu 75 % der Adressraumgröße zu verwenden.
Sie können den sizeof-Operator verwenden, aber er funktioniert nicht für Funktionen, weil er die Referenz des Zeigers nimmt. Um die Länge eines Arrays zu ermitteln, können Sie Folgendes tun:
len = sizeof(arr)/sizeof(arr[0])
Der Code wurde ursprünglich hier gefunden: C-Programm zur Ermittlung der Anzahl der Elemente in einem Array
Wenn Sie den Datentyp des Arrays kennen, können Sie etwas verwenden wie:
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 etwas wie verwenden:
noofele = sizeof(arr)/sizeof(arr[0]);
Hinweis: Dies funktioniert nur, wenn das Array nicht zur Laufzeit definiert ist (wie malloc) und das Array nicht in einer Funktion übergeben wird. In beiden Fällen, arr
(Array-Name) ist ein Zeiger.
int noofele = sizeof(arr)/sizeof(int);
ist nur halbwegs besser als die Codierung int noofele = 9;
. Verwendung von sizeof(arr)
behält die Flexibilität bei, wenn sich die Größe des Arrays ändert. Dennoch sizeof(int)
muss aktualisiert werden, wenn der Typ der arr[]
ändern. Besser zu verwenden sizeof(arr)/sizeof(arr[0])
auch wenn der Typ gut bekannt ist. Unklar, warum die Verwendung von int
para noofele
vs. size_t
ist der Typ, der von sizeof()
.
Das Makro ARRAYELEMENTCOUNT(x)
die jeder nutzt, bewertet falsch . Realistischerweise ist dies eine heikle Angelegenheit, da man keine Ausdrücke haben kann, 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 wird ausgewertet als:
(sizeof (p + 1) / sizeof (p + 1[0]));
.
/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x)[0])
ARRAYELEMENTCOUNT(p + 1);
Es wird korrekt ausgewertet:
(sizeof (p + 1) / sizeof (p + 1)[0]);
Dies hat nicht wirklich viel mit der Größe von Arrays zu tun. Ich habe nur eine Menge Fehler festgestellt, weil ich nicht genau beobachtet habe, wie der C-Präprozessor arbeitet. Man wickelt immer den Makro-Parameter ein, nicht einen Ausdruck, an dem man beteiligt sein könnte.
Das ist richtig; mein Beispiel war schlecht gewählt. Aber das ist eigentlich genau das, was passieren sollte. Wie ich bereits erwähnt habe p + 1
wird als Zeigertyp enden und das gesamte Makro ungültig machen (genauso wie wenn Sie versuchen würden, das Makro in einer Funktion mit einem Zeigerparameter zu verwenden).
Am Ende des Tages, in diesem besondere In diesem Fall spielt der Fehler keine Rolle (ich verschwende also nur jedermanns Zeit), weil es keine Ausdrücke mit dem Typ "array" gibt. Aber ich denke, dass der Punkt über die Subtypen der Präprozessor-Evaluierung wirklich wichtig ist.
Vielen Dank für die Erklärung. Die ursprüngliche Version führt zu einem Kompilierzeitfehler. Clang meldet "subscripted value is not an array, pointer, or vector". Dies scheint in diesem Fall das bessere Verhalten zu sein, obwohl Ihre Anmerkungen zur Auswertungsreihenfolge in Makros gut getroffen sind.
Ich hatte nicht daran gedacht, dass die Compiler-Beschwerde eine automatische Benachrichtigung über einen falschen Typ ist. Dankeschön!
Para mehrdimensionale Arrays es ist ein bisschen komplizierter. Oft werden explizite Makrokonstanten definiert, z.B.
#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 Kompilierzeit ausgewertet werden mit Größe von :
#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. Für Arrays mit mehr als zwei Dimensionen verwenden Sie
sizeof(name[0][0][0])
sizeof(name[0][0][0][0])
usw., bis ins Unendliche.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
6 Stimmen
Zur Typensicherheit siehe stackoverflow.com/questions/19452971/array-size-macro-that-rejects-pointers
0 Stimmen
Eine Antwort ist Gegenstand von eine Metafrage .
1 Stimmen
Wenn die Antworten keinen Sinn ergeben, denken Sie daran, dass beim Kompilieren von C in Assembler die Größeninformation des Arrays verloren geht. Wenn Sie etwas deklarieren wie
int foo[5];
dass 5 nirgendwo in Ihrer kompilierten ausführbaren Datei erscheint.