Frage zu Funktionen: Von oben nach unten?



  • Habe mal eine Frage.

    Ich bin grad an einem kleinen Programm dran. Dort habe ich die Programmwiederholungsfrage in eine eigene Funktion gepackt.

    Also:

    void erneut(void)
    {
    ...
    }
    void main(void)
    {
    ...
    }

    So, jetzt kommt aber mal meine Frage. Ich möchte gerne von der Funktion "erneut" in einen goto Punkt in der Funktion "main" springen, dies geht aber nicht, da es ja 2 unterschiedliche FUnktionen sind, und sich die goto nicht global bewegt, ist dies nicht möglich.

    Dann würde ich einfach von einem Punkt in der "erneut" Funktion in die "main" Funktion springen. Nur wie mache ich das?
    Das Programm sagt stets, das er "main" nicht findet. Habe erst Mittwoch bzw. Freitag nächste Woche wieder Programmieren inner Schule.

    Könnt ihr mich da vllt etwas aufklären, wie das funktioniert?

    Das ich von einer oben stehenden FUnktion in die darunter springen kann.

    Danke für eure Hilfe. lg CiZ



  • Du machst es gar nicht, du designest deine Programmstruktur besser.



  • Eine Lösungmöglichkeit für deine Problem ist:

    int main(void);
    void erneut(void) {
      ...
    }
    int main(void) {
      ...
    
      return 0;
    }
    

    Damit ist die "main"-funktion der "erneut"-funktion bekannt. Desweiteren:

    • Beachte bitte das die Main-Funktion den Rückgabewert int besitzt, dies ist vom C-Standard so vorgeschrieben, void ist falsch.
    • goto ist generell ein sehr verhasste Mittel in der Programmiergemeinde, überlege ob es nicht eine andere elegantere Lösung für dein Problem gibt. Wenn du willst warum -> Google


  • Danke für deine wirklich nette und informationsreiche Antwort. 😋 👍

    Ja, das mit dem goto ist mir schon bekannt, aber mit der for-schleife das so zu umschreiben dauert mir einfach zu lange. kennt ihr vllt einen ersatz?

    Hab bisher in der Schule nur gelernt, das wir anstelle des goto eine for-schleife einbauen sollen, aber das habe ich bis dato immer noch nicht so ganz verstanden. 🙂

    lg CiZ



  • CRUiZOR schrieb:

    Dann würde ich einfach von einem Punkt in der "erneut" Funktion in die "main" Funktion springen. Nur wie mache ich das?

    Wie schon gesagt gar nicht. Explizite Sprünge in C++ sind in den allermeisten Fällen unangebracht, erst recht zwischen mehreren Funktionen.

    Du kannst eine Funktion durch Rückgabewerte und Parameter mit der Aussenwelt kommunizieren lassen (das ist erheblich besser als über globale Variablen!). Mit einer Schleife kannst du eine Wiederholung einbauen. So kann dein Problem bestimmt ohne grauenhafte Hacks gelöst werden.

    x4rd3n schrieb:

    Eine Lösungmöglichkeit für deine Problem ist:

    int main(void);
    void erneut(void) {
      ...
    }
    int main(void) {
      ...
    
      return 0;
    }
    

    Nein, das ist keine Lösungsmöglichkeit. main() sollte man nicht direkt aufrufen, das Problem würde dadurch sowieso nicht behoben.



  • Nein, das ist keine Lösungsmöglichkeit. main() sollte man nicht direkt aufrufen, das Problem würde dadurch sowieso nicht behoben.

    Doch, mein Problem ist gelöst. 🙂 Hab dann halt alles so geschrieben, wie "x4rd3n" schon vorgeschlagen hat.

    Und voila. 🙂

    Es funktioniert. ^^

    Danke euch. Echt super Support hier. 🙂 Bin schon voll erschrocken gewesen nach ca. 5 min meine erste antwort zu bekommen. ^^

    Danke euch.

    Könntet ihr mir vllt. nur noch sagen, was man anstelle von goto einsetzen kann? (Ausser schleifen... :p )

    lg CiZ



  • Nexus schrieb:

    Nein, das ist keine Lösungsmöglichkeit. main() sollte man nicht direkt aufrufen, das Problem würde dadurch sowieso nicht behoben.

    Ich denke x4rd3n wollte nicht die main Funktion erneut aufrufen, sondern er meint, dass goto über Funktionen hinweg geht.
    Das ist aber nicht so:

    6.6.4 The goto statement [stmt.goto]
    1 The goto statement unconditionally transfers control to the statement labeled by the identifier. The identifier
    shall be a label (6.1) located in the current function.
    

    Die besseren Alternativen wurden ja bereits genannt.



  • CRUiZOR schrieb:

    Es funktioniert. ^^

    Schön, aber du willst doch auch etwas lernen und dich nicht mit dem ersten Vorschlag in einem Internetforum zufriedengeben? Falls dein einziges Kriterium jedoch darin besteht, einen Code fehlerfrei zu kompilieren, dann ist dein Problem natürlich schon gelöst.

    CRUiZOR schrieb:

    Könntet ihr mir vllt. nur noch sagen, was man anstelle von goto einsetzen kann? (Ausser schleifen... :p )

    Warum ausser Schleifen? Schleifen sind eines der elementarsten Konstrukte der prozeduralen Programmierung. Wenn du in der Schule einen guten Lehrer hättest, würdest du solche Dinge wie goto erst viel später als Schleifen lernen, wenn überhaupt.



  • Ich habe nicht gerade die besten Lehrer, aber das goto haben die uns eigl. auch schon verboten. 🙂

    Das habe ich unter meinen Kollegn so nebenbei mitgelernt, und fande das als beste Alternative, zu langen Tipparbeiten, wie Schleifen.

    Das heisst aber nicht, das ich niemals Schleifen benutze. Dies mach ich wohl noch, aber wenn das goto kurz seinen Job erledigt, dann reicht mir dies eigl. schon. 🙂

    Naja, hauptsache es funzt, und ausserdem ist mein Programm gerade noch im Alpha Status, und ich werde das goto mit der Zeit entfernen, und im Gegensatz dafür chleifen einbauen. 🙂

    Vllt. sogar schon in der SVN1001... ^^

    Erstmal vielen Dank für eure Ratschläge, aber vorerst ist ja mein Problem gelöst.

    Und zu dem hier:

    Schön, aber du willst doch auch etwas lernen und dich nicht mit dem ersten Vorschlag in einem Internetforum zufriedengeben?

    Wieso nicht? Das sind ja keine Bots die hier antworten, sondern Personen wie ich und hoffentlich auch du. ^^ Dann kann doch auch der erste Ratschlag richtig sein. 🙂

    lg CiZ



  • CRUiZOR schrieb:

    Das habe ich unter meinen Kollegn so nebenbei mitgelernt, und fande das als beste Alternative, zu langen Tipparbeiten, wie Schleifen.

    Tipparbeit ist ein interessanter Punkt, nehmen wir ihn doch etwas genauer unter die Lupe. Hier ein Vergleich zwischen den drei Schleifen-Typen und dem jeweiligen goto -Äquivalent:

    While

    while (bedingung)
        tue_etwas();
    

    vs.

    start:
    if (bedingung)
    {
        tue_etwas();
        goto start;
    }
    

    For

    for (int i = 0; i < 5; ++i)
        tue_etwas();
    

    vs.

    int i = 0;
    start:
    if (i < 5)
    {
        tue_etwas();
        ++i;
        goto start;
    }
    

    Do-While

    do
        tue_etwas();
    while (bedingung);
    

    vs.

    start:
    tue_etwas();
    if (bedingung)
        goto start;
    

    CRUiZOR schrieb:

    Das heisst aber nicht, das ich niemals Schleifen benutze. Dies mach ich wohl noch, aber wenn das goto kurz seinen Job erledigt, dann reicht mir dies eigl. schon. 🙂

    Das Problem ist, dass man als Anfänger die Konsequenzen nicht einschätzen kann. Allein im oberen Code habe ich z.B. der Scope der Variablen i nicht berücksichtigt. Sprünge innerhalb der Funktion verschleiern den tatsächlichen Programmfluss und erzeugen sehr leicht ungewollte Seiteneffekte und Fehlerquellen. Man benötigt im Normalfall länger, eine Konstruktion mit goto zu durchblicken als die äquivalente ohne goto . Im Grossen und Ganzen handelt man sich eine Menge Probleme ein, die erst im grösseren Rahmen voll zum Tragen kommen. Dafür dort umso heftiger.

    CRUiZOR schrieb:

    Naja, hauptsache es funzt

    Ich sehe schon, du musst noch viel lernen. 🙂

    CRUiZOR schrieb:

    Wieso nicht? Das sind ja keine Bots die hier antworten, sondern Personen wie ich und hoffentlich auch du. ^^ Dann kann doch auch der erste Ratschlag richtig sein. 🙂

    Trotzdem darfst du kritisch sein. Es geht zudem nicht nur um die Richtigkeit, wobei der erste Ratschlag hier nicht einmal richtig war. Dass es zu funktionieren scheint, hat weder mit Korrektheit noch mit gutem Codestil zu tun. Das ist eines der in Stein gemeisselten Prinzipien, ohne deren Erkenntnis man als Programmierer verloren ist. Du wirst merken, dass dies umso wichtiger wird, je mehr Code du schreibst. Du solltest dein Urteil nicht aufgrund von 30 Zeilen Code fällen.



  • goto soll man ja immer mit bedacht einsetzen. 🙄



  • einfach so

    bool erneut(void) {
      ...
    }
    int main(void) {
      while( erneut() )
      {
        ...
      }
      return 0;
    }
    

Anmelden zum Antworten