Die Frage, die Sie stellen, besteht eigentlich aus zwei Fragen, nicht aus einer. Die meisten Antworten haben bisher versucht, das Ganze mit einer generischen pauschalen Antwort "Dies ist K & R-Stil" abzudecken, während tatsächlich nur ein kleiner Teil davon etwas mit dem sogenannten K & R-Stil zu tun hat (es sei denn, Sie sehen die gesamte C-Sprache als "K & R-Stil" auf die eine oder andere Weise :)
Der erste Teil ist die seltsame Syntax in Funktion Definition
int func(p, p2)
void *p;
int p2;
{
return 0;
}
Dies ist eigentlich eine Funktionsdefinition im K & R-Stil. Andere Antworten haben dies ziemlich gut abgedeckt. Und da ist eigentlich nicht viel dran. Die Syntax ist veraltet, wird aber auch in C99 noch vollständig unterstützt (mit Ausnahme der Regel "no implicit int" in C99, was bedeutet, dass Sie in C99 die Deklaration von nicht auslassen könnenp2
).
Der zweite Teil hat wenig mit K & R-Stil zu tun. Ich beziehe mich auf die Tatsache, dass die Funktion mit "getauschten" Argumenten aufgerufen werden kann, dh bei einem solchen Aufruf findet keine Parametertypprüfung statt. Dies hat sehr wenig mit der Definition im K & R-Stil an sich zu tun, aber es hat alles damit zu tun, dass Ihre Funktion keinen Prototyp hat. Sie sehen in C, wenn Sie eine Funktion wie diese deklarieren
int foo();
Es deklariert tatsächlich eine Funktion foo
, die eine nicht spezifizierte Anzahl von Parametern unbekannten Typs akzeptiert . Sie können es als nennen
foo(2, 3);
und wie
j = foo(p, -3, "hello world");
ans so weiter (Sie bekommen die Idee);
Nur der Aufruf mit den richtigen Argumenten "funktioniert" (was bedeutet, dass die anderen undefiniertes Verhalten erzeugen), aber es liegt ganz bei Ihnen, die Richtigkeit sicherzustellen. Der Compiler muss die falschen nicht diagnostizieren, auch wenn er die richtigen Parametertypen und deren Gesamtzahl auf magische Weise kennt.
Tatsächlich ist dieses Verhalten ein Merkmal der C-Sprache. Eine gefährliche, aber dennoch eine Besonderheit. Es ermöglicht Ihnen, so etwas zu tun
void foo(int i);
void bar(char *a, double b);
void baz(void);
int main()
{
void (*fn[])() = { foo, bar, baz };
fn[0](5);
fn[1]("abc", 1.0);
fn[2]();
}
dh verschiedene Funktionstypen in einem "polymorphen" Array ohne Typecasts mischen (verschiedene Funktionstypen können hier jedoch nicht verwendet werden). Wiederum sind die inhärenten Gefahren dieser Technik ziemlich offensichtlich (ich erinnere mich nicht, sie jemals benutzt zu haben, aber ich kann mir vorstellen, wo sie nützlich sein kann), aber das ist schließlich C.
Schließlich das Bit, das den zweiten Teil der Antwort mit dem ersten verbindet. Wenn Sie eine Funktionsdefinition im K & R-Stil erstellen, wird kein Prototyp für die Funktion eingeführt. In Bezug auf den Funktionstyp func
deklariert Ihre Definition func
als
int func();
dh weder die Typen noch die Gesamtzahl der Parameter werden deklariert. In Ihrem ursprünglichen Beitrag sagen Sie "... es scheint anzugeben, wie viele Parameter es verwendet ...". Formal gesehen nicht! Nach Ihrer Zwei-Parameter- func
Definition im K & R-Stil können Sie immer noch func
als aufrufen
func(1, 2, 3, 4, "Hi!");
und es wird keine Einschränkungsverletzung darin geben. (Normalerweise gibt Ihnen ein Qualitätscompiler eine Warnung).
Eine manchmal übersehene Tatsache ist auch, dass
int f()
{
return 0;
}
ist auch eine Funktionsdefinition im K & R-Stil, die keinen Prototyp einführt. Um es "modern" zu machen, müssten Sie ein explizites void
in die Parameterliste einfügen
int f(void)
{
return 0;
}
Entgegen einer weit verbreiteten Meinung werden in C99 sowohl Funktionsdefinitionen im K & R-Stil als auch nicht prototypisierte Funktionsdeklarationen vollständig unterstützt. Ersteres ist seit C89 / 90 veraltet, wenn ich mich richtig erinnere. Für C99 muss die Funktion vor der ersten Verwendung deklariert werden, die Deklaration muss jedoch kein Prototyp sein. Die Verwirrung rührt anscheinend von der populären terminologischen Verwechslung her: Viele Leute nennen jede Funktionsdeklaration "einen Prototyp", während "Funktionsdeklaration" nicht dasselbe ist wie "Prototyp".