Mit welcher Funktion kann ich feststellen, wie viele Elemente sich in einem Array char befinden?
sizeof () gibt die Anzahl der verfügbaren „Leerzeichen“ an, damit es für mich nicht funktioniert.
Kommentare
- Können Sie bitte ein Beispiel geben? zB
char foo [100] = "bar";
– meinen Sie das? Sie möchten die Antwort: 3? - ja, dass ' s rechts
Antwort
Sie möchten strlen
.
char foo [100] = "bar"; Serial.println (strlen (foo)); // --> prints 3
Kommentare
- If Wenn die Antwort für Sie funktioniert hat, klicken Sie bitte auf die Schaltfläche " " (es sieht aus wie ein Häkchen). Auf diese Weise wissen andere Leute, dass die Die Lösung hat funktioniert.
- Ich musste einige Minuten warten, um dies zu tun.
- Beachten Sie, dass dies nur funktioniert, wenn die Daten in Ihrer enthält eine ASCII-Zeichenfolge und ist ordnungsgemäß nullterminiert. Wenn Sie eine lange Zeichenfolge in der
char[]
haben und diese mit einer kürzeren Zeichenfolge überschreiben, ohne die Nullterminierung hinzuzufügen, erhalten Sie die Größe der älteren Zeichenfolge. Ganz richtig. Meine Antwort war auf die gestellte Frage. Die Dinge, die Sie erwähnen, sollten für nullterminierte C-Zeichenfolgen berücksichtigt werden.
Antwort
Ich kenne Sie Ich habe Ihre Antwort von @NickGammon, aber ich möchte nur ein bisschen detailliertere Informationen darüber hinzufügen, wie das alles funktioniert.
sizeof()
ist keine Funktion im normalen Sinne des Wortes. Es ist ein Operator, der Ihnen die Anzahl der Speicherbytes angibt, die dem zugewiesen sind, was Sie ihm übergeben. Wenn Sie ihm ein Array übergeben, gibt er die Anzahl der Bytes zurück, die dem Array zur Verfügung stehen. Wenn Sie ihm einen Zeiger auf ein Array übergeben, wird die Größe dieses Zeigers und nicht die Größe des Arrays zurückgegeben. Wenn Sie ihm eine Ganzzahlvariable übergeben, wird die Anzahl der von dieser Ganzzahlvariablen verwendeten Bytes zurückgegeben (2 in einem 8-Bit-Format) System wie AVR, 4 auf einem 32-Bit-System wie Due).
Einige Beispiele:
char array[50] = "hello"; // sizeof(array) = 50. char *array_p = array; // sizeof(array_p) = 2 or 4 depending on architecture. char single = "a"; // sizeof(single) = 1. char string[] = "hello"; // sizeof(string) = 6 (5 letters plus \0) - it allocates the memory at compile time to fit the string
Jetzt strlen()
. Wie genau unterscheidet sich das von sizeof()
? Einfach ausgedrückt, zählt die Anzahl der Zeichen in einem Zeichenarray, bis das Zeichen \0
erreicht ist, das das Abschlusszeichen“ NULL „einer C-Zeichenfolge ist. Nehmen wir die vorherigen Beispiele, verwenden Sie jedoch stattdessen strlen:
char array[50] = "hello"; // strlen(array) = 5. char *array_p = array; // strlen(array_p) = 5. char single = "a"; // strlen(single) = ERROR! strlen() doesn"t operate on single characters. char string[] = "hello"; // strlen(string) = 5.
Sie stellen fest, dass immer die Anzahl der Zeichen in der Zeichenfolge bis zu, jedoch nicht einschließlich zurückgegeben wird. Das nachfolgende Zeichen \0
.
In seiner einfachsten Form könnte die Funktion strlen()
folgendermaßen aussehen:
int strlen(const char *data) { int c = 0; const char *p = data; while (*p) { c++; p++; } return c; }
Grundsätzlich beginnt es beim ersten Zeichen in der Zeichenfolge (*p = data
) und prüft, ob es „sa oder nicht (while (*p)
), erhöht die Anzahl der Zeichen (c++
) und fährt mit dem nächsten Zeichen fort in der Zeichenfolge (p++
).
Wenn Sie Ihre Zeichenfolge in Ihrem Programm durchlaufen möchten, können Sie strlen()
Um zuerst die Anzahl der Zeichen in der Zeichenfolge zu ermitteln, verwenden Sie diesen Wert in einer Schleife. Das ist etwas verschwenderisch, da strlen()
zuerst die Zeichenfolge durchläuft, sodass Sie sie am Ende zweimal durchlaufen. Es ist weitaus effizienter zu lernen, wie Sie die einzelnen Zeichen in der Zeichenfolge am besten durchlaufen, bis Sie das abschließende Zeichen gefunden haben, z. B. wie die Funktion strlen()
den Zeiger um sich durch den Speicher zu bewegen. Sie können auch sehen, wie wichtig es ist, dass Sie sicherstellen, dass das Zeichen \0
am Ende der Zeichenfolge vorhanden ist. Andernfalls funktioniert es wie strlen()
wissen, wann man aufhört? Sie können nicht wissen, wie lang die Zeichenfolge ist (sizeof()
gibt die Größe des übergebenen Zeigers zurück, nicht die Größe des Arrays), daher müssen sie eine Art von haben manuelle Markierung, und die Konvention in C besteht darin, \0
zu verwenden.
Beachten Sie, dass die print()
-Funktionen von Arduino tatsächlich funktionieren mach es sehr ineffizient. Wenn Sie etwas tun wie:
char message[] = "Hello"; Serial.println(message);
Es wird tatsächlich eine Menge Arbeit erledigen, die es nicht wirklich braucht Schritt für Schritt:
- ruft println (Nachricht) auf
- ruft auf (Nachricht)
- ruft die Zeichenfolgenlänge mit strlen (Nachricht) auf
- und ruft write (message, length)
- auf, die dann von 0 bis length-1 durchlaufen und jedes Zeichen der Nachricht nacheinander an write () senden.
- druckt schließlich die
\r\n
für die neue Zeile.
Sie endet also tatsächlich um 4 Funktionen tief verschachtelt und iteriert die gesamte Zeichenfolge zweimal. A. klassisches Beispiel für die Verschwendung von Verarbeitungszeit.Wenn Sie den String einmal durchlaufen und nach dem Zeichen \0
in der Funktion write(message)
(Schritt 2) suchen, wird er mindestens doppelt so schnell ausgeführt. Guter alter Arduino …
Kommentare
- Re „In seiner einfachsten Form könnte die Funktion strlen () so aussehen“, in einer kürzeren ( vielleicht einfacher?) Form könnte es so aussehen:
int strlen(const char *data) { const char *p = data; while (*p++); return p-data-1; }
- @ jwpat7 Ich sagte " am einfachsten ", nicht " kürzester und kompaktester ". Diese Form ist zwar kleiner und effizienter, für das OP (das offensichtlich kein Programmierer ist) jedoch viel schwieriger zu verstehen.
- Einverstanden 🙂 Auch leichter Fehler zu machen Und wenn das
\0
das letzte zugängliche Byte in einem Segment ist, wird das*p++
fehlerhaft sein. Aberint strlen(const char *data) { const char *p = data; while (*p) ++p; return p-data; }
vermeidet dieses Problem. - Tatsächlich hat
*p++
' t Fehler auch dann, wenn\0
das letzte zugängliche Byte in einem Segment ist; Der Teil*p
greift auf das letzte Byte zu. Der ++ – Teil setztp
auf eine ungültige Adresse. Da diese ungültige Adresse jedoch nicht ' referenziert wird, tritt auf einem typischen Computer kein Fehler auf. - Es handelt sich um ein Makro zur Kompilierungszeit … Es ist ' kein Makro , es ' ist ein Operator (wie " + " und " – sind Operatoren). Sie sind niedriger als Makros, die zur Zeit vor dem Prozessor ausgeführt werden. Siehe Größe des Operators . Auch Operatoren in C ++
Antwort
use sizeof char nnn[10]; for(int i=0; i< sizeof(nnn)/sizeof(char); i++){ }
Kommentare
- Haben Sie die Frage richtig gelesen?
- Das OP sagte
sizeof
" ' funktioniert bei mir nicht " und Dann schlagen Sie vor, sizeof zu verwenden. - kann die Frage nicht beantworten, wenn dasselbe unbekannte
verwendet wird