Array von char* soll auf ‘\0’ oder ‘\0’ enden?

Lesezeit: 6 Minuten

Benutzer-Avatar
Andrew-Dufresne

Nehmen wir an, wir haben ein Array von Zeichenzeigern

char* array[] = { "abc", "def" };

Was soll nun am Ende stehen?

char* array[] = { "abc", "def", '\0' };

oder

char* array[] = { "abc", "def", "\0" };

Allerdings funktioniert beides. Wir müssen nur die Bedingung setzen, um das Ende entsprechend zu prüfen

wie

array[ index ] != '\0';

oder

array[ index ] != "\0";

Meine Frage ist, was ist der bessere Weg? Welches wird von den meisten Programmierern verwendet?

Bearbeiten

Die meisten Antworten sagen, dass NULL besser ist als ‘\0’ und “\0”. Aber das dachte ich immer

NULL ist dasselbe wie ‘\0’, was dasselbe ist wie 0x0 oder 0

Ist es falsch?

  • In Bezug auf die Bearbeitung ist In C NULL ein Zeiger (normalerweise definiert (void*)0. ‘\0’ ist eine Zeichenkonstante. Wenn also eine Zeichenkonstante verwendet wird, bei der ein Zeiger erwartet wird, tritt eine implizite Konvertierung auf. Wie es passiert Konvertierung von Jede Ganzzahl Null führt zu einem NULL-Zeiger, aber es macht nicht klar, dass Sie einen Zeiger beabsichtigt haben.Es ist besser, einfach eine wörtliche Konstante Ganzzahl Null IMO zu verwenden.Wie es in C++ passiert, ist dies auf jeden Fall der bevorzugte Ansatz, aber in C++ ist das NULL-Makro auch so definiert (sehen Sie in den Standard-Header-Dateien Ihres Compilers nach).

    – Clifford

    27. September 2009 um 19:49 Uhr

Ich würde es beenden mit NULL. Wieso den? Weil Sie beides nicht tun können:

array[index] == '\0'
array[index] == "\0"

Der erste vergleicht a char * zu einem charwelches ist nicht was du willst. Sie müssten dies tun:

array[index][0] == '\0'

Der zweite geht gar nicht. Du vergleichst a char * zu einem char *, ja, aber dieser Vergleich ist sinnlos. Es ist erfolgreich, wenn die beiden Zeiger auf dasselbe Stück Speicher zeigen. Sie können nicht verwenden == Um zwei Zeichenfolgen zu vergleichen, müssen Sie die verwenden strcmp() Funktion, weil C keine eingebaute Unterstützung für Strings hat, abgesehen von ein paar (und ich meine ein paar) syntaktischen Feinheiten. Wobei folgendes:

array[index] == NULL

Funktioniert einwandfrei und vermittelt deinen Standpunkt.

  • Eigentlich die char* Der Vergleich hat wahrscheinlich für das OP funktioniert, da der Compiler die beiden identischen Zeichenfolgenliterale vereinheitlicht hat. Ich stimme zu, dass der Vergleich im Prinzip bedeutungslos ist.

    – Martin v. Löwen

    27. September 2009 um 10:13 Uhr

  • Ist NULL nicht dasselbe wie ‘\0’? Was ich verstehe ist, dass NULL == ‘\0’ == 0x0. Ist ist falsch?

    – Andrew-Dufresne

    27. September 2009 um 10:36 Uhr

  • Normalerweise ist NULL ((void*)0) … obwohl die Werte gleich sind, sind die Typen unterschiedlich.

    – Fortran

    27. September 2009 um 11:07 Uhr

  • Nitpick – der erste Vergleich ist eigentlich OK – '\0' ist ein ganzzahliger Wert von Null und wird in diesem Zusammenhang als Nullzeigerkonstante ausgewertet. Es ist jedoch keine gute Idee, weil es ein Gefühl der Verwirrung seitens des Autors vermittelt. Wenn du meinst NULLsagen NULL.

    – Café

    27. September 2009 um 11:12 Uhr

  • @caf genau das, was ich gerade schreiben wollte, +1. @Chris, und beachten Sie, dass Zeichenliterale in C tatsächlich einen Typ haben int nicht char (aber das würde nichts an seiner Fähigkeit ändern, eine Nullzeigerkonstante zu sein – char ist auch ein ganzzahliger Typ). Repariere es und ich gebe dir auch +1 xD

    – Johannes Schaub – litb

    27. September 2009 um 14:18 Uhr

Benutzer-Avatar
Christoph

Gemäß der C99-Spezifikation

  • NULL wird zu einer Null-Zeiger-Konstante erweitert, was nicht erforderlich ist, aber typischerweise vom Typ ist void *
  • '\0' ist eine Zeichenkonstante; Zeichenkonstanten sind vom Typ intalso ist es gleichbedeutend mit einfach 0
  • "\0" ist ein nullterminiertes Zeichenfolgenliteral und entspricht dem zusammengesetzten Literal (char [2]){ 0, 0 }

NULL, '\0' und 0 sind alle Nullzeigerkonstanten, so dass sie alle Nullzeiger bei der Konvertierung ergeben, wohingegen "\0" ergibt eine Nicht-Null char * (was behandelt werden sollte als const da Modifikation undefiniert ist); Da dieser Zeiger für jedes Vorkommen des Literals unterschiedlich sein kann, kann er nicht als Sentinel-Wert verwendet werden.

Obwohl Sie jeden ganzzahligen konstanten Wertausdruck verwenden können 0 als Nullzeigerkonstante (zB '\0' oder sizeof foo - sizeof foo + (int)0.0), du solltest benutzen NULL um Ihre Absichten klar zu machen.

  • Obwohl zu sein Ja wirklich Nit Picking, NULL wird nur dann zu einem Nullzeiger erweitert, wenn er als definiert ist (void*)0 (in diesem Fall ist es sowohl das als auch eine Nullzeigerkonstante) 🙂 Wenn es passiert 0 oder ähnliches, dann ist es nur eine Nullzeigerkonstante, die noch in einen Nullzeiger umgewandelt werden muss 🙂

    – Johannes Schaub – litb

    27. September 2009 um 14:27 Uhr

  • @litb: eigentlich '\0' ist möglicherweise keine gültige Nullzeigerkonstante, da es sich um eine Zeichenkonstante (C99 6.4.4.4) und nicht um eine Ganzzahlkonstante (C99 6.4.4.1) handelt; Zeichenkonstanten werden manchmal als ganzzahlige Zeichenkonstanten bezeichnet, aber macht sie das zu einem “ganzzahligen Konstantenausdruck”, wie von C99 6.3.2.3 gefordert?

    – Christoph

    27. September 2009 um 14:55 Uhr

  • @litb: thx – weiß nicht, warum ich nicht selbst nach dem Begriff gesucht habe

    – Christoph

    27. September 2009 um 15:02 Uhr

Von diesen beiden ist der erste ein Typfehler: ‘\0’ ist ein Zeichen, kein Zeiger. Der Compiler akzeptiert es trotzdem, weil er es in einen Zeiger umwandeln kann.

Der zweite “funktioniert” nur zufällig. “\0” ist ein Zeichenfolgenliteral aus zwei Zeichen. Wenn diese an mehreren Stellen in der Quelldatei vorkommen, kann der Compiler sie identisch machen, muss es aber nicht.

Also ist der richtige Weg, den ersten zu schreiben

char* array[] = { "abc", "def", NULL };

und Sie testen für array[index]==NULL. Der richtige Weg, um den zweiten zu testen, ist
array[index][0]=='\0'; Sie können auch das ‘\0’ in der Zeichenfolge weglassen (d. h. buchstabieren als ""), da dies bereits ein Nullbyte enthält.

  • Ich finde es interessant, dass dieses Problem zwei Antworten hat, die funktionieren, aber keine ist technisch korrekt und keine funktioniert aus dem Grund, aus dem das OP glaubt, dass sie es tun.

    – Chris Lutz

    27. September 2009 um 10:19 Uhr

Benutzer-Avatar
ChrisF

Nun, technisch '\0' ist ein Zeichen während "\0" ist eine Zeichenfolge. Wenn Sie also nach dem Null-Terminierungszeichen suchen, ist das erstere korrekt. Wie Chris Lutz in seiner Antwort darauf hinweist, funktioniert Ihr Vergleich jedoch nicht in seiner aktuellen Form.

Der Abschluss eines Arrays von Zeichen mit einem Nullzeichen ist nur eine Konvention, die speziell für Zeichenfolgen in C gilt. Sie haben es mit etwas völlig anderem zu tun – einem Array von Zeichenzeigern –, also hat es wirklich keine Beziehung zur Konvention für C Saiten. Sicher, Sie könnten es mit einem Nullzeiger beenden; das könnte vielleicht Ihre Konvention für Arrays von Zeigern sein. Es gibt andere Möglichkeiten, dies zu tun. Sie können die Leute nicht fragen, wie es funktionieren “sollte”, weil Sie eine Konvention annehmen, die nicht vorhanden ist.

  • Die Konvention gilt für Arrays mit variabler Länge: Verwenden Sie NULL als Sentinel-Wert.

    – u0b34a0f6ae

    27. September 2009 um 11:12 Uhr

Benutzer-Avatar
Alan

Nullterminierung ist ein schlechtes Designmuster, das am besten in den Geschichtsbüchern bleibt. Es gibt immer noch viel Trägheit hinter C-Saiten, also kann es dort nicht vermieden werden. Aber es gibt keinen Grund, es im Beispiel des OP zu verwenden.

Verwenden Sie kein Abschlusszeichen und verwenden Sie sizeof(array) / sizeof(array[0]), um die Anzahl der Elemente zu erhalten.

  • Die Konvention gilt für Arrays mit variabler Länge: Verwenden Sie NULL als Sentinel-Wert.

    – u0b34a0f6ae

    27. September 2009 um 11:12 Uhr

1136460cookie-checkArray von char* soll auf ‘\0’ oder ‘\0’ enden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy