Anfängerfrage Funktionsprototyp



  • Hallo allerseits,
    ich hab hier im Forum mal geschmökert nach Funktionsprototyp und hab dann einiges gefunden an Fehlern wenn der Funktionsprototyp nicht angegeben wird. Ich hab genau das umgekehrte Problem, nämlich der Funktionsprototyp wird absichtlich weggelassen und nichts passiert, der Kompiler (g++) meckert nicht und die Kompilierung funktioniert auch.
    Das Prog. das ich verwende ist im Prinzip ein Beispiel für "call by value" aus Dirk Louis: C/C++ Das komplette Programmierwissen für Studium und Job. Ich hab den Code geringfügig geändert um C++ Code daraus zu machen:
    /* Callval.cpp Call by value mit C++ Konventionen */

    #include <iostream>
    // #include <cstdlib.h>

    using namespace std;

    // void change(int);

    void change(int param)
    {
    // printf("\n\tParam nach Funktionsaufruf: %d\n", param);
    cout << "\n\tParam nach Funktionsaufruf:" << param;
    param = param*param;
    // printf("\tParam nach Berechnung: %d\n\n", param);
    cout << "\tParam nach Berechnung:" << param;
    }

    int main()
    {
    int var=10;
    // printf("var vor Funktionsaufruf: %d\n", var);
    cout << "\nvar vor Funktionsaufruf:" << var;

    // Funktionsaufruf, var wird als value uebergeben

    change(var);

    // printf("var nach Funktionsaufruf: %d\n", var);
    cout << "\nvar nach Funktionsaufruf:" << var;
    cout << "\n";

    return 0;
    }
    Wäre nett wenn mir jemand einen Tip geben könnte.
    Gruß



  • #include <iostream>
    
    using namespace std;
    
    //das wuerde die Funtion deklarieren
    // void change(int);
    
    //das definiert die Funktion
    void change(int param)
      {
      cout << "\n\tParam nach Funktionsaufruf:" << param;
      param = param*param;
      cout << "\tParam nach Berechnung:" << param;
      }
    
    int main()
      {
      int var=10;
      cout << "\nvar vor Funktionsaufruf:" << var;
    
      //die Funktion wurde definiert, also ist alles okay.
      change(var);
    
      cout << "\nvar nach Funktionsaufruf:" << var;
      cout << "\n";
    }
    

    So macht es Probleme:

    #include <iostream>
    
    using namespace std;
    
    int main()
      {
      int var=10;
      cout << "\nvar vor Funktionsaufruf:" << var;
    
      //die Funktion wurde weder deklariert noch definiert -> Fehler.
      change(var);
    
      cout << "\nvar nach Funktionsaufruf:" << var;
      cout << "\n";
    }
    
    //das definiert die Funktion -> Aber hier ist es  zu spät.
    void change(int param)
      {
      cout << "\n\tParam nach Funktionsaufruf:" << param;
      param = param*param;
      cout << "\tParam nach Berechnung:" << param;
      }
    

    Nun schreib mal bei der zweiten Version den Prototypen wieder über die main ...



  • Was Du als "Prototyp" bezeichnest ist auch als Deklaration bekannt. Du brauchst hier keine Deklaration vor der Definition. Eine Definition ist gleichzeitig auch schon eine Deklaration (aber nicht umgekehrt). Dort, wo Du die Funktion aufrufen willst, ist sie schon bekannt, wegen der Definition darüber.



  • Vielen Dank für die schnellen Antworten. Ah, ich denke ich habs verstanden. Die Definition der Funktion ersetzt den Funktionsprototyp (Deklaration), dann und nur dann wenn die Definition vor der ersten Verwendung der Funktion steht. Wenn die Definition nach dem main Block steht ist am Anfang des Programms die Deklaration nötig, weil sonst bei Funktionsaufruf die Funktion nicht bekannt ist.
    Auf die Idee, daß Deklaration und Definition in beiden Fällen explicit vorhanden sein müßte, bin ich durch die Bemerkung in einem Lehrbuch gekommen, daß die Sprache C das Fehlen des Funktionsprototypen eher mal verzeihe, C++ in dieser Hinsicht aber streng sei und der Funktionsprototyp in jedem Fall vorhanden sein müsse.



  • abacus schrieb:

    Vielen Dank für die schnellen Antworten. Ah, ich denke ich habs verstanden. Die Definition der Funktion ersetzt den Funktionsprototyp (Deklaration), dann und nur dann wenn die Definition vor der ersten Verwendung der Funktion steht.

    Die Definition ist immer gleichzeitig eine Deklaration. Egal was wo steht.

    abacus schrieb:

    Wenn die Definition nach dem main Block steht ist am Anfang des Programms die Deklaration nötig, weil sonst bei Funktionsaufruf die Funktion nicht bekannt ist.

    Genau. Stichwort: "one-pass" Compiler verarbeitet werden können muss.

    abacus schrieb:

    Auf die Idee, daß Deklaration und Definition in beiden Fällen explicit vorhanden sein müßte, bin ich durch die Bemerkung in einem Lehrbuch gekommen, daß die Sprache C das Fehlen des Funktionsprototypen eher mal verzeihe, C++ in dieser Hinsicht aber streng sei und der Funktionsprototyp in jedem Fall vorhanden sein müsse.

    Seit C99 geht das auch in C nicht mehr.

    kk



  • Das stammt aus Erlenkötter: C++ Objektorientiertes Programmieren von Anfang an, Ausgabe 2009: "In C++ muß jede Funktion einen Funktionsprototyp haben. C ist da etwas lascher, was die Programme an dieser Stelle im Gegensatz zu C++ fehleranfälliger macht." Vielleicht hat sich aus einer älteren Ausgabe etwas eingeschlichen. Das Beispiel für "call by reference" macht das überflüssigerweise auch so: Funktionsprototyp, Funktionsdefinition, main.
    Ist gut, daß ich jetzt weiß wanns notwendig ist und wann nicht. Aber Erlenkötter ist ansonsten ne ganz kompakte Einführung in objektorientiertes Programmieren mit C++.



  • abacus schrieb:

    Das stammt aus Erlenkötter: C++ Objektorientiertes Programmieren von Anfang an, Ausgabe 2009: "In C++ muß jede Funktion einen Funktionsprototyp haben. C ist da etwas lascher, was die Programme an dieser Stelle im Gegensatz zu C++ fehleranfälliger macht."

    Tja, das ist dann wohl glatt gelogen.

    abacus schrieb:

    Das Beispiel für "call by reference" macht das überflüssigerweise auch so: Funktionsprototyp, Funktionsdefinition, main.

    Hmm... macht den Eindruck, als wüsste der Autor nicht, wovon er spricht. Ich selbst kenne das Buch nicht. Aber ich wäre jetzt an Deiner Stelle sehr vorsichtig. Im schlimmsten Fall ist das Buch voll von Unwahrheiten und schlechten Beispielen. Dann würdest Du C++ nicht richtig lernen. Auf Amazon-Bewertungen kann man sich da auch nicht verlassen. Dieses Buch richtet sich hauptsächlich an Anfänger. Wenn also Otto Normalanfänger kein Vorwissen hat, kann er die Qualität des Buchs nicht richtig einschätzen und vergibt dann schonmal 5 Sterne, weil es "leicht zu lesen war" oder so. Für Buchempfehlungen gibt's hier im Forum aber auch einen entsprechenden Thread. Eventuell findest Du sogar einen Beitrag, der Dein jetziges Buch schlecht macht. "Erlenkötter" hab ich schon ab undzu hier mal gelesen. Ich hab's aber nicht positiv in Erinnerung.



  • Ja danke für den Tip, ich werd mal hier in den Literaturempfehlungen schmökern.


Log in to reply