array_length in C
Schrieb ich einen array_length-Funktion wie diese:
int array_length(int a[]){
return sizeof(a)/sizeof(int);
}
Aber es ist wieder 2, wenn ich nicht
unsigned int len = array_length(arr);
printf ("%i" , len);
wo ich
int arr[] = {3,4,5,6,1,7,2};
int * parr = arr;
Aber wenn ich einfach
int k = sizeof(arr)/sizeof(int);
printf("%i", k);
in der main-Funktion, es gibt 7.
Was ist die richtige Art zu schreiben, die array_length-Funktion und wie benutze ich es?
Obwohl einige Leute in der unten zur Verfügung gestellt haben ein makro, das funktioniert, ist es wichtig zu verinnerlichen, dass C von anderen Sprachen (Java, C#, etc.), arrays wirklich nur Pointer auf einen Speicherblock, und es s bis zu Ihnen, zu verfolgen die Länge. Wenn Sie "get", wird es machen das arbeiten mit C viel, viel einfacher.
InformationsquelleAutor SuperString | 2010-01-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Computing-array-Längen, C, problematisch ist am besten.
Das Problem mit dem code oben, ist, dass, wenn Sie tun:
Du bist wirklich nur auf der Durchreise in einen Zeiger als "a", so
sizeof(a)
istsizeof(int*)
. Wenn Sie auf einem 64bit-system, erhalten Sie immer 2 fürsizeof(a)/sizeof(int)
innerhalb der Funktion, da der Zeiger wird 64-bit.Können Sie (möglicherweise) zu tun, wie ein makro anstelle der Funktion, aber das hat seine eigenen Probleme... (Es vollkommen inlines, also bekommen Sie das gleiche Verhalten wie Ihre
int k =...
block, though.)sizeof(int)==sizeof(int*)
auf einem 64-bit system? Die Größe derint
ist von der Implementierung abhängig, aber immer mindestens 32 bit, oder so dachte ich.Ja, aber es ist kein c-compiler auf der Erde, die sets int = 64 bit. Es sei denn, Sie schreiben oder patch.
es ist möglich, aber ich kenne keine, die das tun. MS + GNU + Intel + die meisten anderen Compilern gesetzt, sizeof(int) == 32...
die alten Cray-C-compiler ich verwendete vor einigen Jahrzehnten hatte der 64-bit-ints...
Mein Verständnis ist, dass die meisten 64-bit-Unix-Systeme verwenden die
ILP64
Modell, woint
64-bit (unix.org/version2/whatsnew/lp64_wp.html). Natürlich, da habe ich wenig Erfahrung auf Unix-Kisten, ich könnte falsch sein. (Windows verwendet das LLP64-Modell, woint
ist 32-bit: blogs.msdn.com/oldnewthing/archive/2005/01/31/363790.aspx).InformationsquelleAutor Reed Copsey
Ihre Funktion wird nicht funktionieren. C-arrays und C-Zeigern gibt verschiedene Arten, aber das array wird ausarten in einen Zeiger, wenn man es lustig.
In diesem Fall sind Sie übergeben Sie das array als parameter, und es verwandelt sich in einen Zeiger im Aufruf, so dass Sie die Messung der
sizeof(int *)/sizeof(int)
.Der einzige Weg, um diese Arbeit zu machen, ist die Verwendung eines Makros:
und das wird nur funktionieren, wenn
x
deklariert ist, in diesem Bereich als array und nicht als Zeiger.InformationsquelleAutor David Thornley
Verwenden Sie ein makro,...
Es haben auch den bonus, die für array Datentyp 🙂
int *foo = NULL; SIZEOF_ARRAY( foo );
Es hat die Tugend der möglicherweise Arbeit korrekt, im Gegensatz zu der Funktion.
Und ist nicht das, was das wichtigste ist: Code, der möglicherweise funktioniert Sie einwandfrei, manchmal?
Bitte setzen Sie Klammern um die ganze makro-expansion...
Das problem ist der OP-das Verständnis von arrays und Zeigern, die die obige Antwort nicht erklären.
InformationsquelleAutor Goz
Im Allgemeinen, es ist unmöglich zu Messen array-Größe C. In der main-Funktion, die der compiler zählt die Elemente, die Sie schrieb zwischen den geschweiften Klammern, so dass Sie wirklich sind deklarieren
int arr[7]
. Das hat die Größe, die Sie erwarten.In Ihrer Funktion, jedoch
int a[]
entsprichtint *a
-- ein Zeiger auf eine Ganzzahl. Sie wissen, dass es ein array, so gibt es mehr ganze zahlen folgende, aber Ihrearray_length
Funktion weitergegeben werden konnten alle integer-Zeiger, so dass es nicht wissen.Dies ist einer der vielen Gründe für die Verwendung
std::vector
anstelle von roh-arrays, Wann immer möglich.std::vector
ist syntax error in C. Der OP ist mit C.Die sagen das ist unmöglich ist ein bisschen übertrieben - es gibt sicherlich Probleme, und es kann nicht immer durchgeführt werden, sauber. Aber es gibt Techniken, dass die Arbeit oft genug, um sehr nützlich sein, trotz der Nachteile.
Aah, ich bin also verwendet, um C++... und ja, ich weiß, es gibt makro-Techniken, wie geschrieben von anderen Menschen, aber Sie scheinen äußerst problematisch für mich. Ich weiß nicht, wie die Idee der "Funktion" (makro), arbeitet für die deklarierten Variablen in dem gleichen Umfang, jedoch nicht für Parameter. Dann jedes mal, wenn Sie es verwenden möchten, müssen Sie daran denken, zu prüfen, wo Sie deklariert die variable, die Sie aufrufen, auf. Wenn Sie vergessen, werde es kompilieren Prima, aber die Ausbeute eklatant falsche Ergebnisse.
das ist eine legitime Sicht. Persönlich finde ich das Dienstprogramm von der makro-auf die Nachteile überwiegt.
InformationsquelleAutor Asher Dunn
Die einfache Antwort auf deine Frage ist: es gibt keine Möglichkeit zu schreiben, die
array_length
Funktion. Sie könnte in der Lage sein, um Weg mit einem makro-definition, aber das hängt von dem Kontext, in dem Sie das makro.Haben Sie machte den Fehler, verwirrend arrays und Zeigern in C. In C wird ein array mit Namen, in den meisten Fällen, ist äquivalent zu einem Zeiger auf sein erstes element. Ihre
array_length
Funktion erhält ein arraya
in einem solchen Kontext. In anderen Worten, ist es unmöglich, übergeben Sie ein array als array in C. die Funktion ist so, als ob es ist wie folgt definiert:welche, im Grunde teilt sich die Größe der
int *
von der Größeint
. Auch nach der obigen Beschreibung, es ist unmöglich zu wissen, die Größe eines Arrays in C in einer Funktion.Nun, wie können Sie bestimmen seine Größe richtig außerhalb der Funktion? Die Antwort ist, dass
sizeof
Betreiber ist einer der Fälle, wo der name eines Arrays hat nicht zu reduzieren, um einen Zeiger auf sein erstes element. Ich habe erklärt, die Unterschiede genauer gesagt in diese Antwort. Auch beachten Sie, dass trotz Auftritte,sizeof
ist ein operator, keine Funktion ist (wie wir gerade gelernt, es nicht eine Funktion sein, weil es dann nicht in der Lage zu berechnen, die Größe eines Arrays).Schließlich, um zu bestimmen, die Größe eines Arrays
a
jeglicher ArtT
ich lieber:Den oben genannten Typ-Agnostiker:
a
könnte sein, oben. In der Tat, man könnte sogar ändern Sie die Art dera
und würde sich nicht ändern müssen, die oben genannten.InformationsquelleAutor Alok Singhal
versuchen _countof es ist definiert in WinNT.h wie
InformationsquelleAutor Bartosz Wójcik
Das problem ist, dass die Parameter der Funktion nicht wirklich arrays, obwohl C können Sie eine Erklärung abgeben, dass sieht aus wie ein. Der parameter endet als einen einfachen Zeiger. Ich habe gesagt,anderswo:
Das ist, warum diese Art von konstruieren, um die Anzahl der Elemente in einem array am Ende ein makro in C. Siehe diese frühere SO Antwort für das, was ich denke, ist eine gute (wenn auch kompliziert) die Umsetzung der makro:
Für eine einfache Referenz, hier ist das makro:
Komplikationen in das makro um es sicherer zu bedienen als die meisten (beachten Sie, ich behaupte nicht, die Urheber der verwendeten Techniken im makro).
InformationsquelleAutor Michael Burr
Dem Allgemeinen Verfahren für die Berechnung der Anzahl der Elemente in einem array ist
sizeof arr /sizeof arr[0]
(odersizeof arr /sizeof *arr
). Having said that...Schreiben Sie eine Funktion zur Berechnung der Länge eines array als argument übergeben, ist zum scheitern verurteilt, denn das, was die Funktion erhält ist ein pointer, kein array. Wenn Sie rufen Sie Ihre Funktion mit einem array-Ausdruck als argument, wird der array-Ausdruck wird dessen Typ implizit aus "array von T" zu "Zeiger auf T", und dessen Wert gesetzt werden, um auf das erste element im array. Ihre Funktion sehen nicht ein array-Objekt; es sieht ein Zeiger.
In den Kontext einer Funktion parameter Erklärung
int a[]
ist genau das gleiche wieint *a
, aber das ist nur gilt für die Funktion parameter-Deklarationen (nichts würde mich glücklicher machen als zu sehen, daß die erste form, verbannt von allen zukünftigen Versionen von C, aber das wird nicht passieren).InformationsquelleAutor John Bode
int arr[was auch immer] innerhalb der Funktion argument-Liste definiert eine Zeiger, und nicht ein array. Also, die Informationen über Länge, ist für immer verloren.
warum!?
Zu sehen, warum, müssen Sie verstehen, was C ist. C kopiert nie komplexe chunks um implizit. Also, wenn Sie sagen "gib mir ein array", es bedeutet eigentlich "ich will, um eine Adresse, die in der array-name der Regel ist".
Dies ist kein Nachteil. Wenn Sie mehr wollen, Sie haben, um es manuell. Die Belohnung ist, dass Sie genau wissen, was Los ist auf der Maschine die Ebene, indem Sie die Leistung und andere Vorteile. Dies ist, wie können Sie das eine Universelle Programmiersprache für alle Zwecke.
InformationsquelleAutor Pavel Radzivilovsky
es gibt keinen Weg, um zu bestimmen, die Größe eines Arrays einer Funktion übergeben werden, wie dies
es ist nicht genügend Informationen zur compile-Zeit oder zur Laufzeit, um es zu
Den sizeof-tricks funktionieren nur in der Quelle Lagen, wo die array-Größe angegeben ist
InformationsquelleAutor pm100
Array-Referenz wird dieses Problem lösen, obwohl ich würde nie empfehlen, so etwas (da es nur funktioniert, wenn Sie entweder immer vorbei, ref, oder verwenden Sie es in dem Umfang, in dem das array definiert wurde):
Auch hier erwähnt: http://cplusplus.co.il/2009/09/06/more-on-arrays/
Edit: Wie vorgeschlagen, in den Kommentaren, eine andere mögliche Lösung ist diese:
mhm, gut 😮 Sorry, habe nicht bemerkt, dass. Ich lasse th Kommentar tho, denn vielleicht ist er in der Lage, die C++ als auch.
Das ist nicht C, aber...
Wenn er C++, sollte er lieber die kanonische
std::size_t size(T (&)[N]) {return N;}
version um eine stärkere Art überprüfen.Ein potenzieller Nachteil der C++ - Lösungen, die einen Wert zurückgeben von der Funktion sind, dass Sie nicht compile-Zeit-Konstanten (ich verstehe, dass das ist nicht das, was der OP gesucht hatte, aber es ist etwas bewusst zu sein). Für eine Lösung, die 100% compile-Zeit und typesafe (aber immer noch erfordert ein bisschen makro verwenden, um die gewünschte Benutzerfreundlichkeit), suchen Sie auf der Microsoft-implemntation mit C++ - templates im Verzeichnis WinNT.h
InformationsquelleAutor rmn
"Int []" - syntax verwendet, die als Funktion argument ist äquivalent zu int *a".
Diese syntax:
Funktioniert nur zur compile-Zeit.
So, während Sie kann man auch schreiben:
int arr[] = {3,4,5,6,1,7,2};
printf("size=%d\n", sizeof(arr));
Funktioniert das nur zur compile-Zeit.
Einen Weg, den Sie bekommen konnte, um dieses zu machen, ist die dynamic arrays und erstellen Sie Ihre eigenen array-Typ.
z.B.
Und benutzen Sie malloc-zum einstellen der Größe. Sie könnte füllen Sie es mit dem Ellipsen.
z.B. dann ruft populate_array(arr, 1,2,3,4,5,6);
siehe stdarg.
Allerdings, da der C-compiler ist sehr wahrscheinlich ein C++ - compiler zu. Denken Sie über die Verwendung von std::vector statt. Die harte Arbeit ist dann für Sie erledigt.
InformationsquelleAutor Matt
Ich fand, dass war eine Falle gemacht, indem Sie unser C-Compiler!
(So ist es eine standard-CPL? C99 oder etwas anderes?)
Schrieb ich folgenden code in der visual studio-2010-Plattform auf x86.
Dann habe ich Sie gebaut, Und zeigte disassembly-code. die Ergebnisse mag:
So, was? Blick auf diese "Vorsicht" markierten Linien!
Wie haben sich unsere c-compiler behandelt unsere C-code?
Wenn ein Zeiger kommt, vor allem, wenn wir schrieb einen Satz wie
etwas = sizeof(ein element in einem array) /sizeof(das erste element des Arrays)
der Compiler analysieren unsere syntax wie die Anzahl der ein array!
Es ist noch nicht fertig.
Getestet habe ich ein "dynamisches array". Ein array der Zuweisung durch malloc etc.
Bauen.. Zerlegen...
Siehst du das? compiler verpassten unsere syntax zu dieser Zeit.
So die Schlussfolgerung ist:
Wenn Sie schreiben einen Satz besonders gerne:
etwas = sizeof(ein element in einem array) /sizeof(das erste element des Arrays)
Compiler verstehen und zu analysieren, die unseren code und Zeichen der array-Kapazität etwas. Nur, wenn die Quell-array eine Feste array, oder ein array hat bereits erklärt Größe zuvor. (Zu dieser Zeit, die Größe ist eine Konstante gespeichert werden dürfen, compiler den Variablen-Tabelle.)
Es im Grunde wie @rmn sagte.
Das ist, was ich gefunden habe. Möglicherweise wertlos sein.
InformationsquelleAutor 0x2333
Funktioniert das ziemlich gut:
InformationsquelleAutor Neil Chowdhury o_O