Forum: Compiler & IDEs Reihenfolge von Funktionen


von Holzi (Gast)


Lesenswert?

Ich versuche in Funktion 1 die Funktion 2 aufzurufen. Aber in Funktion 2 
die unter Funktion 1 steht möchte ich gerne auch Funktion 1 aufrufen!

void funktion 1()
{
  ..
  funktion2();
  ..
}

void funktion 2()
{
  ..
  funktion1();
  ..
}

so funktioniert das aber nicht! Gibt es da einen Trick wie man das 
umgehen kann?

von Doofkopp (Gast)


Lesenswert?

Prototypen?

von A. H. (Gast)


Lesenswert?

1
void funktion1()
2
void funktion2()
3
4
void funktion1()
5
{
6
  ..
7
  funktion2();
8
  ..
9
}
10
11
void funktion2()
12
{
13
  ..
14
  funktion1();
15
  ..
16
}
Wie Doofkopp schon gesagt hat, über Prototypen geht es. Und vermeide 
Leerzeichen in Funktionsnamen, das kann dann nicht funktionieren.

von Ratlos (Gast)


Lesenswert?

Funktionen die sich gegenseitig aufrufen?
Rekursiv, kann zum Stacküberlauf führen,
da hilft dann kein Trick.
Die Reihenfolge der Funktionen im Listing ist eh' egal.

von Jerome (Gast)


Lesenswert?

void function1(void);
void function2(void);

void funktion1()
{
  ..
  funktion2();
  ..
}

void funktion2()
{
  ..
  funktion1();
  ..
}

von A. H. (Gast)


Lesenswert?

Mist, jetzt habe ich etwas vergessen ... am Ende der ersten beiden 
Zeilen muss jeweils ein Semikolon

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Holzi schrieb:
> so funktioniert das aber nicht!

Doch, das tut es. Es muss nur zum Zeitpunkt des Aufrufs einer Funktion 
bekannt sein, daß es sie gibt - C-Programme werden "von oben nach unten" 
übersetzt.

Mit einem Funktionsprototypen kann man genau das erreichen. Der besagt, 
daß es eine Funktion gibt, und welche Datentypen sie nutzt.
Die Implementierung (also der Funktionsrumpf) kann dann irgendwann 
später erfolgen - auch in einem anderen Modul, das erst vom Linker zum 
Programm dazugepackt wird.


In Deinem Beispiel genügt es, die Zeile

void funktion2(void);

vor die Implementierung von funktion1 zu schreiben.

von Mark B. (markbrandis)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Doch, das tut es. Es muss nur zum Zeitpunkt des Aufrufs einer Funktion
> bekannt sein, daß es sie gibt - C-Programme werden "von oben nach unten"
> übersetzt.

Mir ist klar, dass dies in C so ist, aber ehrlich gesagt habe ich nie 
verstanden warum.

Was spräche denn dagegen,
1.) einmal main() zu durchlaufen und festzustellen, welche Funktionen 
aufgerufen werden
2.) nachzuprüfen, ob alle nach 1.) erforderlichen Funktionen auch 
tatsächlich vorhanden sind?

Dass das hier funktioniert:
1
void funktion()
2
{
3
  // tu was
4
}
5
6
int main()
7
{
8
  funktion();
9
  return 0;
10
}

aber das hier nicht:
1
int main()
2
{
3
  funktion();
4
  return 0;
5
}
6
7
void funktion()
8
{
9
  // tu was
10
}

ist doch eigentlich Käse. ;)

Okay, vielleicht gibt es einen super wichtigen Grund, warum es nur genau 
so und nicht anders sein darf. Dann sagt ihn mir bitte :)

von Karl H. (kbuchegg)


Lesenswert?

Mark Brandis schrieb:
> Rufus Τ. Firefly schrieb:
>> Doch, das tut es. Es muss nur zum Zeitpunkt des Aufrufs einer Funktion
>> bekannt sein, daß es sie gibt - C-Programme werden "von oben nach unten"
>> übersetzt.
>
> Mir ist klar, dass dies in C so ist, aber ehrlich gesagt habe ich nie
> verstanden warum.

Weil die Funktionen keineswegs in der gleichen Datei sein müssen. Die 
können irgendwo sein.

> Was spräche denn dagegen,
> 1.) einmal main() zu durchlaufen und festzustellen, welche Funktionen
> aufgerufen werden
> 2.) nachzuprüfen, ob alle nach 1.) erforderlichen Funktionen auch
> tatsächlich vorhanden sind?

Dann hast du 2 Mechanismen
zum einen werden Funktionen in der selben Übersetzungseinheit 
automatisch gefunden
während Funktionen die nicht in dieser Übersetzungseinheit sind, erst 
recht wieder einen Protoypen benötigen.

Was wäre also gewonnen?
Nichts

> Okay, vielleicht gibt es einen super wichtigen Grund, warum es nur genau
> so und nicht anders sein darf. Dann sagt ihn mir bitte :)

Der Compiler wird einfacher, wenn er den Quelltext einfach nur 1 mal 
durchgehen muss.
Vergiss nicht, dass die Ursprünge der meisten Sprachen weit in die 60-er 
Jahre des letzten Jahrhunderts zurückreichen. Damals war Speicherplatz 
noch kostbar und teuer.

von Mark B. (markbrandis)


Lesenswert?

Karl heinz Buchegger schrieb:
> Der Compiler wird einfacher, wenn er den Quelltext einfach nur 1 mal
> durchgehen muss.
> Vergiss nicht, dass die Ursprünge der meisten Sprachen weit in die 60-er
> Jahre des letzten Jahrhunderts zurückreichen. Damals war Speicherplatz
> noch kostbar und teuer.

Gewiss. Darf man aber auch im 21. Jahrhundert keinen 
Multiple-Pass-Compiler für die Sprache C haben?

von Karl H. (kbuchegg)


Lesenswert?

Mark Brandis schrieb:
> Karl heinz Buchegger schrieb:
>> Der Compiler wird einfacher, wenn er den Quelltext einfach nur 1 mal
>> durchgehen muss.
>> Vergiss nicht, dass die Ursprünge der meisten Sprachen weit in die 60-er
>> Jahre des letzten Jahrhunderts zurückreichen. Damals war Speicherplatz
>> noch kostbar und teuer.
>
> Gewiss. Darf man aber auch im 21. Jahrhundert keinen
> Multiple-Pass-Compiler für die Sprache C haben?

Man darf schon.
Aber auch dann darf der Compiler nicht eigenmächtig neue C-Regeln 
erfinden.

Ist vielleicht nicht ganz klar rüber gekommen:
So manches Sprachdetail in den älteren Programmiersprachen hat seine 
Begründung in den limitierten Resourcen von damals.

C hat seine Wurzeln in einer Zeit, in der von einer IDE noch nicht 
einmal geträumt wurde. Projekt, was ist das?

C enstand mit dem Hintergedanken: Da gibt es einen Haufen Source Files, 
die irgendwie durch den Compiler müssen. Und zwar einzeln. Alles andere 
ist Sache des Programmierers.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.