1. Prog. zu Funktionen



  • DirkB schrieb:

    NekoHiTsuna schrieb:

    thihihi, dankeschön, jetzt geht es 🙂
    Wusste nicht dass man die Funktion erst zu einem gewissen Zeitpunkt aufrufen darf 😃

    Welche Werte soll er denn für die Funktionsparameter annehemen?
    Die Namen der Variablen sind Schall und Rauch.
    Der Prototyp braucht die Namen noch nicht einmal:

    int ermitteln (int, int, int, int); //Geht auch
    // Nur dann weißt du nicht mehr wofür die Parameter stehen :-(
    

    Da kannst du auch direkt Zahlenwerte einsetzten.

    hmmm? meinst du also dass ich nach int gleich die zahl setzen könnte? 😕
    aber dann ist dass doch gar nicht für die variable definiert... oder? *verwirrt sei* 😞



  • Nee, beim Funktionsaufruf kannst du Zahlenwerte einsetzen:
    //z.B.

    Rest = ermitteln (Schaden, HP, 0, Hits); // den 3. Parameter nutzt du in der Funktion eh nicht.
    

    oder

    Rest = ermitteln (100, 100000, 0, 2);
    

    War schlecht formuliert 🙄



  • DirkB schrieb:

    Nee, beim Funktionsaufruf kannst du Zahlenwerte einsetzen:
    //z.B.

    Rest = ermitteln (Schaden, HP, 0, Hits); // den 3. Parameter nutzt du in der Funktion eh nicht.
    

    oder

    Rest = ermitteln (100, 100000, 0, 2);
    

    War schlecht formuliert 🙄

    hm, ist mir noch ein klein wenig unklar (klingt für mich noch unlogisch)
    aber trotzdem danke für deine antwort 🙂
    ich werde dann mal mein buch weiterlesen, mal schauen was da jetzt noch alles zu diesem thema kommt 🙂



  • NekoHiTsuna schrieb:

    DirkB schrieb:

    Nee, beim Funktionsaufruf kannst du Zahlenwerte einsetzen:
    //z.B.

    Rest = ermitteln (Schaden, HP, 0, Hits); // den 3. Parameter nutzt du in der Funktion eh nicht.
    

    oder

    Rest = ermitteln (100, 100000, 0, 2);
    

    War schlecht formuliert 🙄

    hm, ist mir noch ein klein wenig unklar (klingt für mich noch unlogisch)
    aber trotzdem danke für deine antwort 🙂
    ich werde dann mal mein buch weiterlesen, mal schauen was da jetzt noch alles zu diesem thema kommt 🙂

    jetzt verstehe ich was du meinst nachdem ich weitergelesen habe 😃
    ... es wird dann erklärt dass es genügt den datentyp reinzuschreiben aber die reihenfolge sollte man einhalten (die reihenfolge der datentypen vor dem aufrufen der funktion)deswegen ist es übersichtlicher dann noch einen name dazuzuschreiben, aber nötig ist es nicht 🙂

    wenn ich das so richtig verstanden habe 🙂



  • Kennst du Funktionen aus dem Mathe-Unterricht? So f(x)=y und so? Unsere Funktionen sind gar nicht unähnlich. Die wollen irgendwelche Werte übergeben bekommen (x) und spucken dafür einen Rückgabewert aus (y). Woher der Übergabewert x kommt, ist egal. Ob du jetzt direkt eine 3 übergibst, oder ob du eine Variable übergibst, die den Wert 3 hat, kommt für die Funktion aufs Gleiche raus.



  • hm, achso.

    mal was anderes nebenbei: habe gerade ein beispiel gehabt wo es um Stack geht...
    naja schaut auch am besten mal das programm an, dann wisst ihr was ich meine, ich verstehe halt nicht wieso es gleich bleibt:

    //Funktion intern: Der Stack
    #include <iostream>
    
    using namespace std;
    
    void erhoehePunkte (int Punkte);
    
    //Hauptprogramm
    int main ()
    {
        //Variablen
        int Punkte = 1000;  //Punkte
    
        cout << "Punkte vor Funktionsaufruf :" << Punkte << endl;
    
        erhoehePunkte (Punkte);
    
        cout << "Punkte nach Funktionsaufruf: " << Punkte << endl;
        system ("PAUSE");
        return 0;
    }
    //erhoehe Punkte
    void erhoehePunkte (int Punkte)
    {
         Punkte+=100;
    }
    

  • Mod

    _matze schrieb:

    Kennst du Funktionen aus dem Mathe-Unterricht? So f(x)=y und so? Unsere Funktionen sind gar nicht unähnlich. Die wollen irgendwelche Werte übergeben bekommen (x) und spucken dafür einen Rückgabewert aus (y). Woher der Übergabewert x kommt, ist egal. Ob du jetzt direkt eine 3 übergibst, oder ob du eine Variable übergibst, die den Wert 3 hat, kommt für die Funktion aufs Gleiche raus.

    Naja, die andere Auffassung ist im Matheunterricht aber auch nicht unverbreitet. Es geht hier um den Unterschied zwischen strict evaluation und non-strict evaluation. Beides sind berechtige Ansichten zum Nutzen von Funktionen und beides findet man sowohl im Alltagsgebrauch als auch in verschiedenen Programmiersprachen. C++ nutzt strict evaluation, der Threadersteller geht von lazy evaluation aus. Das geht natürlich nicht gut.

    Ein typisches Beispiel für eine Sprache mit lazy evaluation ist der C-Präprozessor:

    #define X 1
    #define Y 2
    
    #define foo X + Y
    
    #undef X
    #undef Y
    #define X 4
    #define Y 6
    
    foo   // 4 + 6
    

    edit: Zumindest die Ursprungfrage hatte dieses Problem. Weiteres Lesen des Threads lässt mich vermuten, dass da noch mehr falsche Vorstellungen sind.



  • Die Variable "Punkte" in "erhoehePunkte" ist eine andere Variable als "Punkte" in "main" - die beiden heißen nur gleich.

    Vergleich: Du hast zwei Mülleimer. Einen in der Küche und einen im Keller. Wenn du etwas in den Mülleiner in der Küche reinwirfst, verändert sich der Mülleimer im Keller nicht.

    Das Zauberwort heißt hier "Call-by-value" vs. "Call-by-reference". Danach kannst du ja mal googlen...



  • die zahl 1000 von Punkte wurde ja dennoch an die funktion übertragen...und... hmmm... 😕

    *jumping out the basement-window*

    edit: sehe gerade bei http://blog.gungfu.de/archives/2005/07/05/der-unterschied-zwischen-call-by-value-und-call-by-reference/ dass dort steht dass eine kopie übertragen wird aber x nicht verändert wird. also Punkte=Punkte*100, "die veränderung ist nicht sichtbar innerhalb einer methode" so stand es da ca.. und Punkte bleibt? oder wie ist das zu verstehen... ~bei int & punkte ist es ja sichtbar~ (seid geduldig mit mir, ich brauche immer meine zeit bis ich was verstehe 🙄 )



  • #include <iostream>
    
    void func1(int i) {
      i=2;  //i ist eine lokale Kopie des übergebenen Wertes.
    }
    
    void func2(int& i) {
      i=2;  //i ist eine Referenz auf die übergebene Variable
    }
    
    int main() {
      int test=1;
    
      func1(test);   //Übergabe by-value
      std::cout << test;  //test ist immer noch 1
    
      func2(test);   //Übergabe by-reference
      std::cout << test;  //test ist nun 2
    }
    


  • wann kommen diese 2 varianten denn zum einsatz?



  • NekoHiTsuna schrieb:

    wann kommen diese 2 varianten denn zum einsatz?

    Na ja, call-by-value ist quasi der Standard. call-by-reference nimmst du immer dann, wenn du einen Grund dazu hast. Beispiel: du willst eine Funktion schreiben, die die Werte zweier int-Variablen vertauscht. Hier bietet sich call-by-reference an:

    void swap(int& a, int& b) {
      int temp=a;
      a=b;
      b=temp;
    }
    


  • Sobald du Abstrakte Datentypen (ADT) benutzt (kommt später denke ich mal) möchtest du nicht jedesmal das komplette Objekt kopieren, deshalb ist es dort auch in etwa 95% der Fälle ein Call-Per-Referenz.

    Zum lazy-Evaluation: Haskell ist auch ein typisches Beispiel. Streng genommen benutzt der Präprozessor nicht lazy-Evaluation, weil das ist definiert durch leftmost-outermost-Graphreduction, und letzteres ist dabei nicht erfüllt 😉



  • _matze schrieb:

    Na ja, call-by-value ist quasi der Standard.

    Bei den eingebauten Datentypen vielleicht. Größere Objekte sollen standardmäßig als const Referenz übergeben werden.



  • ich sag jetzt einfach mal ok xD

    naja, erstmal vielen dank für die ganzen antworten 🙂



  • Hast du dich denn entscheiden können?



  • für was entscheiden?


Anmelden zum Antworten