C-Funktionssyntax, nach der Parameterliste deklarierte Parametertypen

79

Ich bin relativ neu in C. Ich bin auf eine Form der Funktionssyntax gestoßen, die ich noch nie gesehen habe und bei der die Parametertypen nach dieser Parameterliste definiert werden. Kann mir jemand erklären, wie es sich von der typischen C-Funktionssyntax unterscheidet?

Beispiel:

John
quelle

Antworten:

65

Dies ist die alte Syntax für Parameterlisten, die weiterhin unterstützt wird. In K & R C können Sie auch die Typdeklarationen weglassen, und sie werden standardmäßig auf int gesetzt. dh

wäre die gleiche Funktion.

Ferruccio
quelle
17
Sowohl C89 / 90 als auch C99 unterstützen weiterhin offiziell Deklarationen im K & R-Stil. In C99 müssen jedoch alle Parameter explizit deklariert werden (keine "implizite int" -Regel mehr).
AnT
1
Ich hasse es, zu spät zur Party zu kommen (wie 4 Jahre später?), Aber wollen Sie damit sagen, dass sie in C99 explizit in der Parameterliste oder in der Funktion deklariert werden müssen ? Zum Beispiel die Standard-Int-Regel - da sie nicht mehr standardmäßig int sind, müssen ihre Typen vor der Verwendung in der Funktion deklariert werden, wenn die Typen nicht in der Parameterliste angegeben wurden.
Chris Cirefice
1
@ChrisCirefice Um Ihnen 4 Jahre später zu antworten: In C99 müssen alle Parameter in der Parameterliste deklariert werden. Variablen, die in der Funktion deklariert sind, wurden nie standardmäßig intdeklariert und müssen daher explizit deklariert werden.
Frank Kusters
28

Interessant ist auch der Unterschied zwischen Funktionen und Funktionen ohne Prototyp. Betrachten Sie eine alte Stildefinition:

In diesem Fall lautet die aufrufende Konvention, dass alle Argumente heraufgestuft werden, bevor sie an die Funktion übergeben werden (z. B. wird ein floatArgument zuerst heraufgestuft double, bevor es übergeben wird). Wenn also fein doubleParameter empfangen wird , der Parameter jedoch einen Typ hat float(der vollkommen gültig ist), muss der Compiler vor der Ausführung des Funktionskörpers Code ausgeben, der das Double in einen Float konvertiert.

Wenn Sie einen Prototyp einfügen, führt der Compiler solche automatischen Heraufstufungen nicht mehr durch, und alle übergebenen Daten werden wie durch Zuweisung in die Parametertypen des Prototyps konvertiert. Folgendes ist also nicht legal und führt zu undefiniertem Verhalten:

In diesem Fall würde die Definition der Funktion den übermittelten Parameter von double(das heraufgestufte Formular) in konvertieren , floatda die Definition im alten Stil ist. Der Parameter wurde jedoch als Float übergeben, da die Funktion einen Prototyp hat. Zum Beispiel gibt Clang

main.c: 3: 9: Warnung: Der heraufgestufte Typ 'double' des K & R-Funktionsparameters ist nicht kompatibel mit dem in einem früheren Prototyp deklarierten Parametertyp 'float' [-Wknr-geworbener-Parameter]

Sie haben folgende Möglichkeiten, um die Widersprüche zu lösen:

Option 2 sollte bevorzugt werden, wenn Sie die Wahl haben, da die alte Stildefinition von vornherein entfernt wird. Wenn solche widersprüchlichen Funktionstypen für eine Funktion in derselben Übersetzungseinheit angezeigt werden, werden Sie normalerweise vom Compiler darüber informiert (dies ist jedoch nicht erforderlich). Wenn solche Widersprüche über mehrere Übersetzungseinheiten hinweg auftreten, bleibt der Fehler möglicherweise unbemerkt und kann zu schwer vorhersehbaren Fehlern führen. Es ist am besten, diese alten Stildefinitionen zu vermeiden.

Johannes Schaub - litb
quelle
10

Dies ist die so genannte Deklaration im K & R-Stil oder im alten Stil .

Beachten Sie, dass sich diese Erklärung erheblich von der modernen Erklärung unterscheidet. Die K & R-Deklaration führt keinen Prototyp für die Funktion ein, was bedeutet, dass die Parametertypen nicht dem externen Code ausgesetzt werden.

Ameise
quelle
4

Es gibt keinen Unterschied, es ist nur die alte Syntax für Funktionsdeklarationen in C - sie wurde vor ANSI verwendet. Schreiben Sie niemals einen solchen Code, es sei denn, Sie planen, ihn Ihren Freunden aus den 80ern zu geben . Hängen Sie auch niemals von impliziten Typannahmen ab (wie eine andere Antwort zu vermuten scheint).

aviraldg
quelle
Gut vor C99; Es wurde vor ANSI verwendet, das 1989 standardisiert wurde, aber der Prozess begann 1983.
Brian Campbell
2
Ahem ... K & R-Stildeklarationen werden von C99 mit nur einer geringfügigen Änderung weiterhin offiziell unterstützt - kein "implizites int" mehr, alle Parameter müssen explizit deklariert werden.
AnT
Inmitten der Kritik muss ich sagen, dass ich Ihnen zustimme: Tun Sie es nicht.
BobbyShaftoe
4

Während die alte Syntax für die Funktionsdefinition weiterhin funktioniert (mit Warnungen, wenn Sie Ihren Compiler fragen), bietet die Verwendung dieser Funktionen keine Funktionsprototypen.
Ohne Funktionsprototypen prüft der Compiler nicht, ob die Funktionen korrekt aufgerufen werden.

Wenn das Programm ausgeführt wird, ist die Ausgabe auf meinem Computer

pmg
quelle
1

Es ist genauso, aber altmodisch. Sie haben wahrscheinlich festgestellt, dass es sich um einen alten Legacy-Code handelt.

Augen
quelle
0

Alt oder nicht, ich würde argumentieren, was alt ist und was nicht ... wie die Pyramiden alt sind, aber keiner der heutigen sogenannten Wissenschaftler hat eine Ahnung, wie sie hergestellt wurden. Rückblickend funktionieren alte Programme noch heute ohne Speicherlecks, aber diese "neuen" Programme scheitern häufig. Ich sehe hier einen Trend.

Wahrscheinlich sahen sie Funktionen als Strukturen, die einen ausführbaren Körper haben. Kenntnisse in ASM sind hier erforderlich, um das Rätsel zu lösen.

Bearbeiten, ein Makro gefunden, das angibt, dass Sie überhaupt keine Argumentnamen angeben müssen.

Hier ist ein Verwendungsbeispiel, Bibliothek ist zlib-1.2.11 .

Meine zweite Vermutung wäre also die Überladung von Funktionen, sonst hätten diese Argumente keine Verwendung. Eine konkrete Funktion und jetzt unendlich viele Funktionen mit demselben Namen.

Ako
quelle