Frage zu Funktionen



  • Hi Community!
    Ich habe eine Frage bzg. Funktionen

    Wie kann ich Variablen die in der Main
    Funktion deklariert sind in einer normalen Funktion verwenden?

    #include <iostream>
    #include <windows.h>
    
    using namespace std;
    
    int _TestFunktion(int _test);
    
    int main(){
    
     int test;
    
    }
    
    int _TestFunktion(int _test)
    {
     //Jetzt z.B eine Rechnung und das Ergebnis in "test" in der main Funktion       speichern.
      _test = 10;
      test = 5 * _test;
      return test; //?
    }
    

    Irgendwas muss ich da verpasst haben.....
    mit Return will das bei mir auch nicht funktionieren 🙂

    MFG: N290 (mal wieder^^)



  • int foo(int& test) {
    test = 5;
    }
    
    int main() {
       int test;
       foo(test);
       return 0;
    
    }
    


  • Damit du auch noch verstehst, was da gemacht wird: Durch das & im int& test wird test per reference übergeben. Das heißt, es wird im Speicher keine Kopie der Variablen test angelegt, sondern es wird genau auf dem in main reservierten Speicher gearbeitet.
    Call by value hingegen macht genau das Gegenteil und unterscheidet sich syntaktisch dadurch, dass das & entfällt. Es wird eine Kopie der Variablen im Speicher angelegt und auf der werden dann innerhalb der Funktion irgendwelche Operationen durchgeführt.
    Generell ist eine Übergabe per reference also auch immer effizienter. D.h. man sollte das überall wo es möglich bzw. sinnvoll ist auch machen. Müssen Variablen zusätzlich nicht verändert werden, ist eine Übergabe à la "const int& test" natürlich noch besser.



  • Wow Danke! 🙂
    Werd ich gleich mal Versuchen 😉



  • g0nz0 schrieb:

    Müssen Variablen zusätzlich nicht verändert werden, ist eine Übergabe à la "const int& test" natürlich noch besser.

    Worauf stützt du das? Bei PODs war ich bisher der Meinung das es ziemich egal ist ob du das per const ref oder per (const) value übergibst. Bei UDTs würde ich auch zur const ref greifen.


  • Mod

    Das hat mit POD oder nicht nicht viel zu tun, sondern eher mit der Größe. Man spart sich so eben eine Kopie. Bei Datentypen die so groß sind wie die Wortbreite des Prozessors macht dies aber nichts und man vermeidet eine Indirektion wodurch es insgesamt schneller sein kann.

    Übergabe per const value ist ziemlich unsinnig und trägt nur dazu bei, das Interface verwirrend zu machen, weil man Implementierungsdetails in die Schnittstelle aufnimmt.



  • padreigh schrieb:

    g0nz0 schrieb:

    Müssen Variablen zusätzlich nicht verändert werden, ist eine Übergabe à la "const int& test" natürlich noch besser.

    Worauf stützt du das? Bei PODs war ich bisher der Meinung das es ziemich egal ist ob du das per const ref oder per (const) value übergibst. Bei UDTs würde ich auch zur const ref greifen.

    Wenn das POD-obj wiederum 1000 POD-obj als member hat, wirds nicht egal sein 😛



  • Verwirrt ihr immer gern Anfänger? 😃


  • Mod

    N290 schrieb:

    Verwirrt ihr immer gern Anfänger? 😃

    Kommt drauf an, wie sie ihre Fragen stellen. Hier lag es nicht an dir. Es wurde einfach nur etwas falsches behauptet, was richtig gestellt werden musste. Dazu muss man bei der Begründung eben auch mal weiter ausholen und spart durch Verwendung von Fachbegriffen viel Text. padreigh wird meine Erklärung verstehen.



  • Das ist immer gut 🙂
    Danke für die Antworten

    Edit:

    Ist es Sinnvoll lange Funktionen in einer
    neuen Datei (Header?) zu packen?



  • N290 schrieb:

    Ist es Sinnvoll lange Funktionen in einer
    neuen Datei (Header?) zu packen?

    Ich würde sie in die .cpp-Datei packen. Sowieso sollten die meisten Funktionsdefinitionen in der .cpp-Datei sein, da man sich so unnötige Compilezeit-Abhängigkeiten einspart (einerseits muss man Benutzer nicht bei jeder Änderung neu kompilieren, andererseits müssen für die Implementierung benötigte Header nicht auch vom Benutzer eingebunden werden).



  • Ah danke 🙂



  • SeppJ schrieb:

    Das hat mit POD oder nicht nicht viel zu tun, sondern eher mit der Größe. Man spart sich so eben eine Kopie. Bei Datentypen die so groß sind wie die Wortbreite des Prozessors macht dies aber nichts und man vermeidet eine Indirektion wodurch es insgesamt schneller sein kann.

    Gerade nochmal hier: http://www.c-plusplus.net/forum/194356 nachgesehen - hatte PODs falsch im Kopf - was ich meinte sind arithmetische Typen (also das bis 64bit Länge), danke für die Richtigstellung.

    SeppJ schrieb:

    Übergabe per const value ist ziemlich unsinnig und trägt nur dazu bei, das Interface verwirrend zu machen, weil man Implementierungsdetails in die Schnittstelle aufnimmt.

    D.h du würdest

    void machWas(int eins, int zwei) 
    {
      /* eins und zwei dürfen in der Implementierung warumauchimmer nicht verändert werden - evtl eine Hilfsfunktion die auf Teilen von Membervariablen operiert */ 
    }
    // statt
    void machWasConstiges(const int eins, const int zwei) 
    {
      /* ... */ 
    }
    

    angeben weil es die Schnittstelle vereinfacht?


  • Mod

    padreigh schrieb:

    void machWas(int eins, int zwei) 
    {
      /* eins und zwei dürfen in der Implementierung warumauchimmer nicht verändert werden - evtl eine Hilfsfunktion die auf Teilen von Membervariablen operiert */ 
    }
    // statt
    void machWasConstiges(const int eins, const int zwei) 
    {
      /* ... */ 
    }
    

    angeben weil es die Schnittstelle vereinfacht?

    😕 Irgendwie hast du nicht verstanden was ich meine und zeigst genau wie man es nicht macht. Beides davon ist vollkommener Unsinn. Ob du in deiner Implementierung Kopien von irgendwelchen Variablen veränderst oder nicht interessiert niemanden.



  • <a href= schrieb:

    GotW #6: Const Correctness">1. Since the point object is passed by value, there is little or no benefit to declaring it const.

    2. Same comment about the parameter as above. Normally const pass-by-value is unuseful and misleading at best.

    14. This 'const' is equally useless, but for a different reason: since you're passing the pointer by value, this makes as little sense as passing a parameter 'const int' above.



  • Wenn mehr als eine Person an etwas arbeitet und die erste kreiert sowas

    void gibElementAus(int a) 
    { 
      std::cout << m_vec.at(a);
    }
    

    und der nächste wurschtelnt dann darin rum und macht

    void gibElementAus(int a) 
    { 
      for( int i=0; i<5; a+=i)
        std::cout << m_vec.at(a);
    }
    

    draus ... dann verhindert so ein const sowas schon

    Cave: völlig sinnbefreite Beispiele

    Also warum KEIN const in die Methode rein? Das egal ob mit oder ohne const keine Seiteneffekte ausserhalb zu erwarten sind ist mir klar ... Zieh mir gerade mal Nexus Link rein, vielleicht geht mir dann ein Licht auf ...



  • @padreigh: Was intern geschieht, hat rein gar nichts mit der Schnittstelle zu tun. In der Funktionsdeklaration hat das const nicht aufzutreten, da es für den Aufrufer keine Information beinhaltet und nur Verwirrung stiftet. Und auch in der Definition ist der Nutzen beschränkt.

    Aber lies den Artikel von Herb Sutter...



  • Ok, überzeugt. 🙂 http://www.gotw.ca/gotw/ braucht hier irgendwo nen PermaLink 🙂


Anmelden zum Antworten