web-dev-qa-db-de.com

Was bedeutet das Symbol\0 in einem String-Literal?

Betrachten Sie den folgenden Code:

char str[] = "Hello\0";

Was ist die Länge eines Str-Arrays und mit wie viel 0 endet es?

47
UmmaGumma

sizeof str ist 7 - 5 Bytes für den "Hallo" -Text plus den expliziten NUL-Terminator plus den impliziten NUL-Terminator.

strlen(str) ist 5 - nur die fünf "Hallo" Bytes.

Der Schlüssel hier ist, dass der implizite nul-Terminator immer hinzugefügt wird - auch wenn das String-Literal gerade mit \0 endet. Natürlich hält strlen nur beim ersten \0 an - es kann den Unterschied nicht erkennen.

Es gibt eine Ausnahme für die implizite NUL-Terminatorregel. Wenn Sie die Arraygröße explizit angeben, wird die Zeichenfolge entsprechend gekürzt:

char str[6] = "Hello\0"; // strlen(str) = 5, sizeof(str) = 6 (with one NUL)
char str[7] = "Hello\0"; // strlen(str) = 5, sizeof(str) = 7 (with two NULs)
char str[8] = "Hello\0"; // strlen(str) = 5, sizeof(str) = 8 (with three NULs per C99 6.7.8.21)

Dies ist jedoch selten nützlich und neigt dazu, die Länge der Zeichenfolge falsch zu berechnen und am Ende mit einer nicht abgeschlossenen Zeichenfolge zu enden. Es ist auch in C++ verboten.

84
bdonlan

Die Länge des Arrays ist 7, das NUL-Zeichen \0 zählt weiterhin als Zeichen und die Zeichenfolge wird immer noch mit einem impliziten \0 abgeschlossen.

Siehe this link , um ein funktionierendes Beispiel zu sehen

Wenn Sie str als char str[6]= "Hello\0"; deklariert haben, wäre die Länge 6, da die implizite NUL nur hinzugefügt wird, wenn sie passt (was in diesem Beispiel nicht möglich ist.)

§ 6.7.8/S. 14
Ein Array von Zeichentyp kann mit einem .__ initialisiert werden. Zeichenkettenliteral, optional in geschweifte Klammern eingeschlossen. Erfolgreich Zeichen der Zeichenfolge Literal (einschließlich des abschließenden Nullzeichens Wenn Raum vorhanden ist oder wenn das Array eine unbekannte Größe hat) Initialisieren Sie die Elemente des Arrays.

Beispiele

char str[] = "Hello\0"; /* sizeof == 7, Explicit + Implicit NUL */
char str[5]= "Hello\0"; /* sizeof == 5, str is "Hello" with no NUL (no longer a C-string, just an array of char). This may trigger compiler warning */
char str[6]= "Hello\0"; /* sizeof == 6, Explicit NUL only */
char str[7]= "Hello\0"; /* sizeof == 7, Explicit + Implicit NUL */
char str[8]= "Hello\0"; /* sizeof == 8, Explicit + two Implicit NUL */
10
SiegeX

Schlag mein übliches Schlagzeugsolo von JUST TRY IT , so kannst du in der Zukunft solche Fragen beantworten:

$ cat junk.c
#include <stdio.h>

char* string = "Hello\0";

int main(int argv, char** argc)
{
    printf("-->%s<--\n", string);
}
$ gcc -S junk.c
$ cat junk.s

... die unnötigen Teile weglassen ...

.LC0:
    .string "Hello"
    .string ""

...

.LC1:
    .string "-->%s<--\n"

...

Beachten Sie, dass die Zeichenfolge, die ich für printf verwendet habe, nur "-->%s<---\n" ist, während die globale Zeichenfolge aus zwei Teilen besteht: "Hello" und "". Der Assembler GNU beendet auch Zeichenfolgen mit einem impliziten NUL-Zeichen. Die Tatsache, dass sich die erste Zeichenfolge (.LC0) in diesen beiden Teilen befindet, zeigt an, dass es zwei NULs gibt. Die Zeichenfolge ist also 7 Byte lang. Wenn Sie wirklich wissen möchten, was Ihr Compiler mit einem bestimmten Code-Block macht, sollten Sie ihn in einem Dummy-Beispiel wie diesem isolieren und sehen, was er mit -S tut (für GNU - MSVC hat auch ein Assembler-Flag Ausgabe, aber ich weiß es nicht von Hand). Sie erfahren viel darüber, wie Ihr Code funktioniert (oder je nach Fall nicht funktioniert), und Sie erhalten schnell eine Antwort, die zu 100% zu den Tools und der Umgebung passt, in denen Sie arbeiten.

Ich möchte insbesondere eine Situation erwähnen, durch die Sie verwirren können.

Was ist der Unterschied zwischen "\ 0" und ""?

Die Antwort lautet, dass "\0" im Array {0 0} und ""{0} darstellt.

Weil "\0" immer noch ein Stringliteral ist und am Ende "\0" hinzugefügt wird. Und "" ist leer, fügen aber auch "\0" hinzu.

Wenn Sie dies verstehen, werden Sie "\0" gründlich verstehen.

4
YongHao Hu

Was ist die Länge eines Str-Arrays und mit wie viel 0 endet es?

Lass es uns herausfinden:

int main() {
  char str[] = "Hello\0";
  int length = sizeof str / sizeof str[0];
  // "sizeof array" is the bytes for the whole array (must use a real array, not
  // a pointer), divide by "sizeof array[0]" (sometimes sizeof *array is used)
  // to get the number of items in the array
  printf("array length: %d\n", length);
  printf("last 3 bytes: %02x %02x %02x\n",
         str[length - 3], str[length - 2], str[length - 1]);
  return 0;
}
3
Fred Nurk
char str[]= "Hello\0";

Das wären 7 Bytes.

Im Gedächtnis wäre es:

48 65 6C 6C 6F 00 00
H  e  l  l  o  \0 \0

Bearbeiten: 

  • Was bedeutet das Symbol\0 in einer C-Zeichenfolge?
    Es ist das "Ende" einer Zeichenfolge. Ein Nullzeichen Im Speicher ist es eigentlich eine Null. Normalerweise suchen Funktionen, die Zeichenarrays behandeln, nach diesem Zeichen, da dies das Ende der Nachricht ist. Ich werde am Ende ein Beispiel geben.

  • Was ist die Länge eines Str-Arrays? (Beantwortet vor dem Bearbeitungsteil)
    7

  • und mit wie viel 0s endet es?
    Ihr Array hat zwei "Leerzeichen" mit Null; str [5] = str [6] = '\ 0' = 0

Zusätzliches Beispiel:
Nehmen wir an, Sie haben eine Funktion, die den Inhalt dieses Text-Arrays druckt. Sie könnten ihn folgendermaßen definieren:

char str[40];

Jetzt können Sie den Inhalt dieses Arrays ändern (ich werde mich nicht mit Details befassen), so dass es die Meldung enthält: "Dies ist nur ein Drucktest" Im Arbeitsspeicher sollten Sie etwa Folgendes haben:

54 68 69 73 20 69 73 20 6a 75 73 74 20 61 20 70 72 69 6e 74
69 6e 67 20 74 65 73 74 00 00 00 00 00 00 00 00 00 00 00 00

So drucken Sie dieses Zeichen-Array. Und dann möchtest du eine neue Nachricht. Sagen wir einfach "Hallo"

48 65 6c 6c 6f 00 73 20 6a 75 73 74 20 61 20 70 72 69 6e 74
69 6e 67 20 74 65 73 74 00 00 00 00 00 00 00 00 00 00 00 00

Beachten Sie die 00 in str [5]. So weiß die Druckfunktion, wie viel sie tatsächlich senden muss, trotz der tatsächlichen Länge des Vektors und des gesamten Inhalts.

0
L. Lopez