Suche…


Vergleich von Literal und Variable

Angenommen, Sie vergleichen den Wert mit einer Variablen

if ( i  == 2) //Bad-way
{
    doSomething;
}

Angenommen, Sie haben == mit = verwechselt. Dann braucht es deine süße Zeit, um es herauszufinden.

if( 2 == i) //Good-way
{
    doSomething;
}

Wenn versehentlich ein Gleichheitszeichen ausgelassen wird, beschwert sich der Compiler über eine „versuchte Zuweisung von Literalen“. Dies schützt Sie nicht beim Vergleich zweier Variablen, aber jedes kleine bisschen hilft.

Sehen Sie hier für weitere Informationen.

Lassen Sie die Parameterliste einer Funktion nicht leer - verwenden Sie void

Angenommen, Sie erstellen eine Funktion, die beim Aufruf keine Argumente erfordert, und Sie stehen vor dem Dilemma, wie Sie die Parameterliste im Funktionsprototyp und in der Funktionsdefinition definieren.

  • Sie haben die Wahl, die Parameterliste sowohl für den Prototyp als auch für die Definition leer zu lassen. Dabei sehen sie genauso aus wie die Funktionsaufruf-Anweisung, die Sie benötigen.

  • Sie haben irgendwo gelesen, dass eine der Verwendungen des Schlüsselworts void (es gibt nur einige davon) gibt, ist die Definition der Parameterliste der Funktionen, die in ihrem Aufruf keine Argumente akzeptieren. Das ist also auch eine Wahl.

Welches ist die richtige Wahl?

ANTWORT: Verwenden Sie das Schlüsselwort void

ALLGEMEINE HINWEISE: Wenn eine Sprache bestimmte Funktionen enthält, die für einen bestimmten Zweck verwendet werden sollen, ist es besser, diese in Ihrem Code zu verwenden. Verwenden Sie beispielsweise enum s anstelle von #define Makros (das ist ein anderes Beispiel).

C11 Abschnitt 6.7.6.3 "Funktionsdeklaratoren", Absatz 10, bestimmt:

Der Sonderfall eines unbenannten Parameters vom Typ void als einziges Element in der Liste gibt an, dass die Funktion keine Parameter hat.

Paragraph 14 desselben Abschnitts zeigt den einzigen Unterschied:

… Eine leere Liste in einem Funktionsdeklarator, die Teil einer Definition dieser Funktion ist, gibt an, dass die Funktion keine Parameter hat. Die leere Liste in einem Funktionsdeklarator, der nicht Teil einer Definition dieser Funktion ist, gibt an, dass keine Informationen zu Anzahl oder Typ der Parameter angegeben werden.

Eine vereinfachte Erklärung von K & R (S. 72-73) für das oben genannte Zeug:

Wenn eine Funktionsdeklaration keine Argumente enthält, wie in
double atof(); atof bedeutet auch, dass von den Argumenten von atof nichts angenommen werden atof . Alle Parameterüberprüfung ist deaktiviert. Diese besondere Bedeutung der leeren Argumentliste soll älteren C-Programmen ermöglichen, mit neuen Compilern zu kompilieren. Aber es ist keine gute Idee, es mit neuen Programmen zu verwenden. Wenn die Funktion Argumente akzeptiert, deklarieren Sie sie. Wenn es keine Argumente erfordert, verwenden Sie void .

So sollte Ihr Funktionsprototyp aussehen:

int foo(void);

Und so sollte die Funktionsdefinition sein:

int foo(void)
{
    ...
    <statements>
    ...
    return 1;
}

Die Verwendung des obigen Deklarationstyps " int foo() (dh ohne Verwendung des Schlüsselworts void ) hat den Vorteil, dass der Compiler den Fehler erkennen kann, wenn Sie Ihre Funktion mit einer fehlerhaften Anweisung wie foo(42) aufrufen. Diese Art einer Funktionsaufrufanweisung würde keine Fehler verursachen, wenn Sie die Parameterliste leer lassen. Der Fehler würde unbemerkt unbemerkt weitergegeben und der Code würde immer noch ausgeführt.

Das bedeutet auch, dass Sie die main() Funktion folgendermaßen definieren sollten:

int main(void)
{
    ...
    <statements>
    ...
    return 0;
}

Beachten Sie, dass eine mit einer leeren Parameterliste definierte Funktion zwar keine Argumente enthält, jedoch keinen Prototyp für die Funktion bereitstellt. Der Compiler beschwert sich also nicht, wenn die Funktion anschließend mit Argumenten aufgerufen wird. Zum Beispiel:

#include <stdio.h>

static void parameterless()
{
    printf("%s called\n", __func__);
}

int main(void)
{
    parameterless(3, "arguments", "provided");
    return 0;
}

Wenn dieser Code in der Datei proto79.c gespeichert proto79.c , kann er unter GCC (Version 7.1.0 unter macOS Sierra 10.12.5 für Demonstrationszwecke) unter Unix folgendermaßen kompiliert werden:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -pedantic proto79.c -o proto79
$

Wenn Sie mit strengeren Optionen kompilieren, erhalten Sie Fehler:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -pedantic proto79.c -o proto79 
proto79.c:3:13: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
 static void parameterless()
             ^~~~~~~~~~~~~
proto79.c: In function ‘parameterless’:
proto79.c:3:13: error: old-style function definition [-Werror=old-style-definition]
cc1: all warnings being treated as errors
$

Wenn Sie der Funktion den formalen Prototyp static void parameterless(void) , führt die Kompilierung zu Fehlern:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -pedantic proto79.c -o proto79 
proto79.c: In function ‘main’:
proto79.c:10:5: error: too many arguments to function ‘parameterless’
     parameterless(3, "arguments", "provided");
     ^~~~~~~~~~~~~
proto79.c:3:13: note: declared here
 static void parameterless(void)
             ^~~~~~~~~~~~~
$

Moral - Stellen Sie immer sicher, dass Sie Prototypen haben, und stellen Sie sicher, dass Ihr Compiler Ihnen sagt, wenn Sie sich nicht an die Regeln halten.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow