Parameter einer funktion



  • ahh jetzt versteh ichs glaub ich 🙂

    pageNum wird so zu sagen umgewandelt in PrintHeader(4711);

    is das so ungefähr richtig 🙄

    #include <iostream>
    using namespace std;
    
    void PrintHeader(int pageNum);
    
    int main ( )
    {
    PrintHeader(4711);     
    
    getchar();
    }
    
    void PrintHeader(int pageNum)
    {
       cout << "Dies ist Seite " << pageNum << endl;
    
    }
    


  • sAmson ftw schrieb:

    ahh jetzt versteh ichs glaub ich 🙂

    pageNum wird so zu sagen umgewandelt in PrintHeader(4711);

    Fast - pageNum wird mit dem Wert (hier 4711) initialisiert, wenn deine Funktion aufgerufen wird.



  • ok thx :xmas1:



  • Jetzt bin ich bei der Called-by-value Parameter

    Quellcode aus dem Tutorials

    void PrintHeader (int pageNum);
    ....
    int main ( )
    {
        int pNum = 1;        // pNum initialisieren
        PrintHeader(pNum);   // Funktion aufrufen
        ...                  // pNum ist hier immer noch 1!
        PrintHeader(10);     // fixe Seitennummer
    }
    // Funktionsdefinition
    void PrintHeader(int pageNum)
    {
       cout << "Seiten-Nummer: " << pNum << endl;
       pageNum = 99;         // Parameter verändern
    }
    

    Quellcode aus dem Tutorial ohne Fehler:

    #include <iostream>
    using namespace std;
    
    void PrintHeader (int pageNum);
    
    int main ( )
    {
        int pNum = 1;        // pNum initialisieren
        PrintHeader(pNum);   // Funktion aufrufen
                             // pNum ist hier immer noch 1!
        PrintHeader(10);     // fixe Seitennummer
    
        getchar();
    }
    // Funktionsdefinition
    void PrintHeader(int pageNum)
    {
       cout << "Seiten-Nummer: " << pageNum << endl;
       pageNum = 99;         // Parameter verändern
    }
    

    Weiss jemand wofür das hier steht: pageNum = 99; // Parameter verändern

    als Kommentar steht dort ja Parameter verändnern ich hab mal die zahl von 99 auf 3 geändert aber da passiert ja gar nichts 🙄 wofür soll denn dann das pageNum = 99; gut sein man kann es ja auch ganz weg lassen.

    :xmas1: :xmas2:



  • Das soll dir zeigen, daß der Parameter eine Kopie des übergebenen Wertes ist - und die Änderung keine Auswirkungen auf das Hauptprogramm hat. Im nächsten Kapitel lernst du dann, wie du ein anderes Verhalten erzwingen kannst (Referenzparameter).



  • Du kannst dir Funktionsparameter wie eine lokale Variable vorstellen, d.h. du kannst sie innerhalb der Funktion verändern (solange sie nicht als const deklariert sind).

    In dem Beispiel-Code macht das sicherlich wenig Sinn, da die Variable danach nicht mehr benutzt wird (aber sie ändert auch nicht den Wert der übergebenen Variable, dies passiert erst bei Referenzen).

    Hier vll. mal ein Beispiel für die Änderung des Funktionsparameters:

    void printstars(int count)
    {
      while(count > 0)
      {
        std::cout << '*';
        count--; // Parameter lokal verändern
      }
    }
    


  • Das soll verdeutlichen, dass wenn Du eine Funktion per call-by-value aufrufst, den Parameter innerhalb der Funktion ändern kannst und sich auch nur auf diesen Bereich bezieht.
    Schreib doch am Ende der Funktion noch ein "cout"

    // Funktionsdefinition
    void PrintHeader(int pageNum)
    {
       cout << "Seiten-Nummer: " << pNum << endl;
       pageNum = 99;         // Parameter verändern
       cout << pageNum << endl; // Nach der Änderung
    }
    

    Dann siehst Du was passiert..



  • Ok thx



  • sAmson ftw schrieb:

    Jetzt bin ich bei der Called-by-value Parameter...

    Was dir der Autor zeigen wollte ist, das der Wert selbst wenn du ihn in der Funktion änderst, bei Übergabe "Call-by-Value" nur innerhalb der Funktion geändert ist.

    Ich werde es mal etwas näher erläutern, wobei ich wohl dem Tutorial vorgreife:
    (Anmerkung: Code ist ungetestet)

    #include <iostream>
    
    void ChangeValue_CallByValue(int b);
    void ChangeValue_CallByReference(int& b);
    
    int main()
    {
      int a = 4;
      std::cout << "Wert von a ist " << a << std::enld;
      ChangeValue_CallByValue(a);
      std::cout << "Wert von a ist " << a << std::enld;
      ChangeValue_CallByReference(a);
      std::cout << "Wert von a ist " << a << std::enld;
    
      return 0;
    }
    
    void ChangeValue_CallByValue(int b)
    {
      b = 10;
      std::cout << "Wert vom Parameter b wurde innerhalb ChangeValue_CallByValue auf "
        << b << " geändert." << std::endl;
    }
    
    void ChangeValue_CallByReference(int& b)
    {
      b = 20;
      std::cout << "Wert vom Parameter b wurde innerhalb ChangeValue_CallByReference auf "
        << b << " geändert." << std::endl;
    }
    

    Folgende Ausgabe sollte eigentlich kommen:

    Wert von a ist 4
    Wert vom Parameter b wurde innerhalb ChangeValue_CallByValue auf 10 geändert.
    Wert von a ist 4
    Wert vom Parameter b wurde innerhalb ChangeValue_CallByReference auf 20 geändert.
    Wert von a ist 20

    Dazu eine Erklärung:

    In main() legst du eine Variable a an. Sprich du hast irgendwo im Speicher einen Bereich der den int Wert enthält und innerhalb von main() mit dem Namen "a" gültig ist. Am Ende deiner main() Funktion wird der Speicherbereich wieder gelöscht, da die Variable nur innerhalb des Bereiches in dem sie definert ist gültig ist.

    Nun rufen wir ChangeValue_CallByValue auf und übergeben ihr a als Parameter. Wenn man aber genau hinter die Kulisen schaut wird hier wie der Name sagt nur der Wert übergeben.

    a (aus main) ist 4.
    ==> Übergabe des Wertes an den ersten Parameter
    b (aus ChangeValue_CallByValue) wird mit dem Wert von a (4) initialisiert, ist aber eine eigene Variable.

    Das heißt eine Änderung an diesem Parameter ändert auch nur den Wert des Parameters, der am Ende der Funktion seinen Scope verlässt.

    Daher liefert die main-Funktion anschließend auch wieder das a den Wert 4 hat.

    Nun rufen wir ChangeValue_CallByReference auf. Das int& definiert keinen Wert in dem Sinne, sondern nur einen Aliasnamen (einen alternativen Namen für die übergebene Variable):

    a (aus main) ist 4.
    ==> Übergabe als Referenz
    b (aus ChangeValue_CallByReference) ist ein Aliasname für a (aus main)

    Wenn du nun innerhalb der Methode b veränderst ist dies eine Änderung an der gleichen Variable, nur unter einem alternativen Namen (Die Namen können dabei auch beide identisch gewählt sein).

    cu André



  • Edit: So is besser. 😃



  • Ok thx

    Jetzt guck ich mir gerade in dem Tutorial das Beispiel an:

    #include <iostream>
    #include <cmath>
    using std::cout;
    using std::endl;
    
    // PrototyPIKng
    double BerechneSin(double wert);
    
    int main()
    {
        // Konstante PIK definieren
        const double PI = 3.1416;
    
        // Berechne Sinus(0.5) mittels Reihe
        cout << "sin(0.5) : Berechnet = " << BerechneSin(0.5);
        // Und nun Sinus(0.5) mittels Bibliotheksfunktion
        cout << ", Bibl-Funktion = " << sin(0.5) << endl;
        // Das ganz nun fuer PI (3.1416);
        cout << "sin(PI)  : Berechnet = " << BerechneSin(PI);
        cout << ", Bibl-Funktion = " << sin(PI) << endl;
        // und zum Schluss fuer PI/2
        cout << "sin(PI/2): Berechnet = " << BerechneSin(PI/2.0);
        cout << ", Bibl-Funktion = " << sin(PI/2.0) << endl;
    }
    
    // Funktion: BerechneSin
    //           Berechnet Sinus mittels Reihe
    //              sin(x) = x - x^3/3! + x^5/5! - x^7/7!
    // Parameter wert: Wert aus dem Sinus berechnet werden soll
    double BerechneSin(double wert)
    {
        // Ergebnis mit dem Wert vorinitialisieren
        // 1. Term in der Reihe
        double erg = wert;
        // Divident (Nenner) mit wert^3 vorbelegen
        double divident = wert*wert*wert;
        // Divisor (Teiler) 3! vorbelegen
        double divisor = 1.0*2.0*3.0;       // 3!
        // Zweiten Term vom Ergebnis subtrahieren
        erg -= divident/divisor;
        // Dritten Term zum Ergebnis addieren
        divident *= wert*wert;              // wert^5
        divisor *= 20.0;                    // 3! * 4 * 5 = 5!
        erg += divident/divisor;
        // Vierten Term wieder vom Ergebnis subtrahieren
        divident *= wert*wert;              // wert^7
        divisor *= 42.0;                    // 5! * 6 * 7 = 7!
        erg -= divident/divisor;
        // Ergebnis zurückliefern
        return erg;
    }
    

    und wenn ich das Compiliere bekomme ich folgende Fehlermeldungen.

    Erzeugen
    [C++ Fehler] Unit1.cpp(17): E2268 Aufruf der undefinierten Funktion 'sin'
    [C++ Fehler] Unit1.cpp(20): E2268 Aufruf der undefinierten Funktion 'sin'
    [C++ Fehler] Unit1.cpp(23): E2268 Aufruf der undefinierten Funktion 'sin'

    Schon zweite Fehler in dem Tutorail 😡

    ps. Hat vielleicht wer ein beispiel wo nur Addiert und Subtrahiert wird ich habs net so mit Mathe ^^



  • Ja, da fehlt noch ein 'using std::sin;' am Anfang (direkt hinter den übrigen using's).

    Zur Erklärung: Die von C geerbten Standard-Header existieren in zwei Varianten in C++ - <math.h> packt alle enthaltenen Funktionen in den globalen Namensraum, <cmath> in den Namensraum 'std' (genau wie die eigenen Standardheader von C++).



  • ok thx


Anmelden zum Antworten