In einer meiner Projektquelldateien habe ich diese C-Funktionsdefinition gefunden:
int (foo) (int *bar)
{
return foo (bar);
}
Hinweis: Neben befindet sich kein Sternchen foo
, daher handelt es sich nicht um einen Funktionszeiger. Oder ist es? Was ist hier mit dem rekursiven Aufruf los?
c
function
parentheses
user1859094
quelle
quelle
a(b);
? Deklarationb
als Variable des Typsa
? Oder ein Aufruf,a
mit Argumenten zu funktionierenb
? Der Unterschied ist syntaktisch, und Sie können nicht wissen, wie Sie ihn überhaupt analysieren können, ohne die Deklarationsinformationen von nachzuschlagena
. Dies sind die Klammern für Postfix-Funktionsaufrufe oder optionale Klammern um einen Deklarator.Antworten:
Wenn keine Präprozessor-Inhalte vorhanden sind, entspricht
foo
die Signatur derDer einzige Kontext, in dem ich gesehen habe, wie Leute scheinbar unnötige Klammern um Funktionsnamen setzen, ist, wenn sowohl eine Funktion als auch ein funktionsähnliches Makro mit demselben Namen vorhanden sind und der Programmierer die Makroerweiterung verhindern möchte.
Diese Vorgehensweise mag zunächst etwas seltsam erscheinen, aber die C-Bibliothek stellt einen Präzedenzfall dar, indem sie einige Makros und Funktionen mit identischen Namen bereitstellt .
Ein solches Funktions / Makro-Paar ist
isdigit()
. Die Bibliothek kann es wie folgt definieren:Ihre Funktion sieht fast identisch mit der oben genannten aus, daher vermute ich, dass dies auch in Ihrem Code vor sich geht.
quelle
foo(bar)
Innere der Funktion verwendet das entsprechende Makro.foo (int* bar)
ersetzt wird, jedoch nicht(foo) (int *bar)
(das nächste Token) nachfoo
ist)
)(isdigit)(5)
?Die Klammern ändern die Deklaration nicht - sie definieren immer noch nur eine gewöhnliche Funktion, die aufgerufen wird
foo
.Der Grund, warum sie verwendet wurden, ist mit ziemlicher Sicherheit, dass es ein funktionsähnliches Makro namens
foo
defined gibt:Die Verwendung
(foo)
in der Funktionsdeklaration verhindert, dass dieses Makro hier erweitert wird. Was also wahrscheinlich passiert, ist, dass eine Funktionfoo()
definiert wird, wobei ihr Körper aus dem funktionsähnlichen Makro erweitert wirdfoo
.quelle
Die Klammern sind bedeutungslos.
Der Code, den Sie anzeigen, ist nichts anderes als eine unendliche Rekursion.
Wenn Sie einen Funktionszeiger definieren, sehen Sie manchmal seltsame Klammern, die etwas bedeuten. Dies ist hier jedoch nicht der Fall.
quelle