Was bedeutet if((x=0)) in C?

Lesezeit: 6 Minuten

Benutzer-Avatar
Benutzer56220

Anscheinend kompiliert ein Compiler in gcc/C wann

if ((x=0)){ some code }

verwendet wird, während wann

if (x=0){ some code }

verwendet wird, weigert sich der Compiler zu kompilieren.

Was sind die Unterschiede zwischen zwei?

Als Anmerkung, ich weiß, was der Unterschied zwischen ist x==0 und x=0. Ich untersuche gerade, wie sich C verhält, wenn es auf einige seltsame Codes stößt.

  • Und ich kann nicht verstehen, warum jemand das tun möchte if ((x=0)) {...} da diese Bedingung immer falsch sein wird. (Oder x=N für jede Konstante N.) Wenn dies ein Code ist, auf den Sie in freier Wildbahn gestoßen sind, hat vielleicht jemand versucht, die Warnung zu unterdrücken, ohne zu verstehen, wofür die Warnung war.

    – flauschige

    21. September 2014 um 17:10 Uhr

  • Übrigens, ein einfacher Trick, um viele Fälle zu erkennen, in denen = anstelle von == verwendet wurde, besteht darin, die Konstante immer auf der linken Seite zu platzieren — ‘if(0=x)’ erzeugt ein can’t-assign-to – Ständiger Fehler.

    – Keschlam

    21. September 2014 um 18:04 Uhr


  • @keshlam Auch bekannt als Yoda-Bedingungen.

    – Paläc

    21. September 2014 um 18:05 Uhr

  • Auch bekannt als Ihren Code weniger lesbar machen, weil Sie befürchten, dass Sie nicht wissen, wie man eintippt. 🙂

    – chao

    22. September 2014 um 4:09 Uhr

  • Welche Version von GCC und mit welchen Switches? Mit -Wallschlägt Red Hat 4.8.3-1 vor Klammern um die als Wahrheitswert verwendete Zuweisungaber es lässt sich gut kompilieren …

    – Denis

    22. September 2014 um 4:25 Uhr

Es gibt keinen Unterschied, Code-weise.

Alles, was passiert, ist dieser Spruch x=0 Anstatt von x==0 ist ein so häufiger Fehler, dass die meisten Compiler eine Warnung (oder in Ihrem Fall einen Fehler) ausgeben, wenn sie ihn sehen. Der zusätzliche Satz Klammern ist ein gängiger Trick, um den Compiler zum Schweigen zu bringen – das Äquivalent zu sagen: “Ja, ich wollte das wirklich tun”.

  • Ich vermute, es gibt keine gute Antwort außer „weil sie es nicht wollten“, fürchte ich. Die zusätzlichen Klammern sind jetzt so allgegenwärtig, um dem Compiler mitzuteilen, dass er die Warnung unterdrücken soll, dass es sich jetzt wahrscheinlich nicht ändern wird.

    – David gegeben

    21. September 2014 um 15:33 Uhr

  • @LưuVĩnhPhúc: Du sagst ausdrücklich, dass du weißt, was du tust und das = ist kein Tippfehler.

    – Jack

    21. September 2014 um 16:49 Uhr

  • @wildplasser – häufig bedeutet nicht, dass es jedes Mal dieselbe Person macht.

    – Rob Starling

    21. September 2014 um 22:35 Uhr

  • @wildplasser: … sowie jeder Experte, der Doppeltippen vermasselt =. Oder macht einfach einen kurzen Denkfehler.

    Benutzer1084944

    22. September 2014 um 0:30 Uhr


  • @wildplasser Zusätzlich zu dem, was Rob und Hurkyl gerade gesagt haben, gehen Sie davon aus, dass Sie vor zehn Jahren der einzige Programmieranfänger in der Geschichte waren und dass es jetzt keine Programmieranfänger mehr gibt und es auch nie geben wird Zukunft.

    – Lily Chung

    22. September 2014 um 0:44 Uhr


Benutzer-Avatar
Pavel Simerda

Beides ist syntaktisch korrektes C und der Compiler muss damit klarkommen. Aber der Compiler kann je nach Konfiguration eine Warnung oder sogar einen Fehler ausgeben (z. B. -Werror in gcc), weil einer von ihnen so verdächtig ist, dass Sie niemals erwarten würden, dass dies beabsichtigt ist. Wenn Sie etwas wie verwenden if (x = 0) { ... } (Ordnen Sie Null zu x und führe den Block aus, wenn Null nicht Null ist), meinst du fast immer tatsächlich if (x == 0) { ... } (Führen Sie den Block aus, wenn x ist null).

Kommen wir nun zum Warum if ((x = 0)) { ... } wird nicht als verdächtig genug angesehen, um die gleiche Art von Warnung zu rechtfertigen (dieser spezielle Code ist immer noch verdächtig, da die Bedingung immer mit Null ausgewertet wird und der Körper niemals ausgeführt wird) …

Es gibt eine von einigen C-Entwicklern (ich bin einer von ihnen) verwendete Redewendung, bei der Sie eine Zuweisung in Klammern setzen und die Funktion nutzen, dass sogar die Zuweisung selbst einen Wert hat, und zwar den zugewiesenen Wert.

Beispiel:

#include <stdio.h>

int main(int argc, char **argv)
{
    int c;

    while ((c = getchar()) != '\n')
            printf("Character: '%c' (0x%02x)\n", c, c);

    return 0;
}

Testen Sie das Beispiel:

$ ./test
Hello!
Character: 'H' (0x48)
Character: 'e' (0x65)
Character: 'l' (0x6c)
Character: 'l' (0x6c)
Character: 'o' (0x6f)
Character: '!' (0x21)

Entscheidend war der Zustand (c = getchar()) != '\n' wo Sie zuerst das Ergebnis zuweisen getchar() zu c und dann auf einen bestimmten Wert prüfen. In diesem Fall lesen wir Zeichen nacheinander von der Standardeingabe bis zum und einer Zeile (technisch gesehen bis zum Lesen von a \n Charakter). Der Hauptvorteil dieser Vorgehensweise besteht darin, dass Sie die Füllung füllen können getchar() in die Prüfung. Andernfalls müssten Sie die Kommanotation verwenden, eine Endlosschleife mit Unterbrechung, oder sie sowohl vor die Schleife als auch an das Ende der Schleife setzen.

Manchmal vergleichen Sie mit Werten ungleich Null, wie z \n, -1 und ähnliches, aber manchmal vergleichen Sie mit Null oder, wenn Sie mit Zeigern arbeiten, mit NULL. Suchen wir ein Beispiel für NULLwas bei der Speicherzuweisung ziemlich üblich ist.

char *p;

if ((p = malloc(50)) == NULL) {
    ...handle error...
}

Man könnte es natürlich schreiben als:

char *p;

p = malloc(50);
if (p == NULL) {
    ...handle error...
}

Aber je nach Geschmack könnte man auch verwenden:

char *p;

if (!(p = malloc(50))) {
    ...handle error...
}

Oder drehen Sie es sogar umgekehrt (was übrigens dagegen spricht mein Bevorzugung, immer zuerst den Fehlerfall zu behandeln):

char *p;

if ((p = malloc(50))) {
    ...do stuff...
} else {
    ...handle error...
}

Im letzten Fall ist die Bedingung (p = malloc(50)) was genau äquivalent ist p = malloc(50) letzteres ist aber wegen des bereits erwähnten höchst verdächtig gemeinsames Fehler bei der Durchführung einer Zuweisung anstelle eines Vergleichs in C und abgeleiteten Sprachen. Beachten Sie, dass es nicht nur um verdächtige Compiler geht, sondern auch um Menschen, die den Code lesen und sich den potenziellen Fehler ansehen.

Die redundanten Klammern sind einfach ein Mittel, um den Lesern und dem Compiler mitzuteilen, dass diese Zuweisung definitiv beabsichtigt ist und dass es sich nicht um ein Auftreten dieses häufigen Fehlers handelt.

  • EIN konform C-Compiler darf auch nicht ablehnen if (x = 0) oder if ((x = 0)). Es kann vor allem warnen, was ihm gefällt, einschließlich des Hemdes, das Sie tragen.

    – Keith Thompson

    21. September 2014 um 20:07 Uhr

  • @PavelŠimerda: Der Punkt ist, dass Compiler vor allem warnen können, was sie möchten.

    – Keith Thompson

    21. September 2014 um 20:33 Uhr

  • @PavelŠimerda: Nein, ich habe einen wichtigen und gültigen Punkt angesprochen (mit einer kleinen Prise Humor).

    – Keith Thompson

    21. September 2014 um 21:21 Uhr

  • @PavelŠimerda: Lesen Sie den Kommentar als “der Standard würde es dem Compiler erlauben, vor allem zu warnen, was ihm gefällt – sogar vor Dingen, die einem C-Compiler nicht wichtig sein sollten – vorausgesetzt, dass die Warnungen nicht die Kompilierung eines konformen Programms verhindern “. Notiere dass der -Werror Option verlangt vom Compiler ein Verhalten, das dem Standard widerspricht, aber für viele Programmierer nützlicher ist.

    – Superkatze

    21. September 2014 um 21:56 Uhr

  • Jeder Compiler, der sein Geld wert ist, sollte vor Hawaiihemden warnen.

    – Martijn

    22. September 2014 um 10:46 Uhr

Der Code sollte sich nicht “weigern”, zu kompilieren, es sei denn, Sie haben es getan -Werror. Wenn Sie Warnungen aktiviert haben, wird Ihnen möglicherweise Folgendes angezeigt:

Warnung: Schlägt Klammern um die als Wahrheitswert verwendete Zuweisung vor [-Wparentheses]
while (*dest++ = *src++)

Insbesondere die GCC-Dokumente Sagen Sie dies über den Zweck der Warnung:

Warnen Sie, wenn Klammern in bestimmten Kontexten weggelassen werden, z. B. wenn eine Zuweisung in einem Kontext vorhanden ist, in dem ein Wahrheitswert erwartet wird, oder wenn Operatoren verschachtelt sind, deren Vorrang häufig verwirrt wird.

1373000cookie-checkWas bedeutet if((x=0)) in C?

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

Privacy policy