Falls sich die Frage mehr darauf bezog, wie man denn die Argumente
in diesem Falle auswertet, dann hier noch als (historische)
Ergänzung:
Die Deklaration lautet, wie schon genannt:
Die kann man bspw. in eine Headerdatei schreiben, damit der Compiler
weiß, dass es am Ende im Projekt irgendwo eine Funktion namens foo()
gibt. (*)
In irgendeiner der Quelldateien steht dann die Definition für
foo(), und die könnte beispielsweise folgendermaßen aussehen:
1 | int
|
2 | foo(argc, argv)
|
3 | int argc;
|
4 | char **argv;
|
5 | {
|
6 | /* do something */
|
7 | return 42;
|
8 | }
|
Selbstverständlich war (ist) das ganze Verhalten nur definiert, wenn
der Aufrufer dann auch mit Parametern passender Typen (also "int" und
"char **") aufgerufen hat, aber wie Karl Heinz schon schrieb, der
Compiler hatte halt keine Chance, das noch zu überprüfen, und zuweilen
wurde das dann auch missbraucht, um eine implizite Typkonvertierung
gleich noch mit durchzudrücken.
Aber wie schon geschrieben, seit ANSI-C89 ist das Geschichte und
sollte da bleiben, wo es hingehört: in historischem C-Code. Man
sollte es halt noch kennen, damit man ganz altes C lesen kann.
Benutzen sollte man das im 3. Jahrtausend nicht mehr.
(*) Ganz Faule haben die Deklaration auch noch weggelassen, und der
Compiler hat die Faulheit unterstützt, indem er beim Aufruf einer
nicht deklarierten Funktion implizit "int" als Rückkehrtyp angenommen
hat. Dazumals war außerdem ein "int" praktisch noch komplett mit
einem beliebigen Zeiger austauschbar, sodass man, bis auf
float/double, eigentlich komplett ohne Funktionsdeklarationen auskam,
wenn man schön schlampig programmieren wollte. ;-)