Übergabe von mehreren Variablen von Unter- an Haptprogramm



  • Hallo liebe cpp-Experten,

    ich möchte ein Programm mit einem Unterprogramm schreiben, das mehrere im Unterprogramm geänderte Variable an das Hauptprogramm zurückgibt.

    Da es bei cpp keine common-Blocks gibt wie bei Fortran habe ich damit Probleme.

    Meine Frage an Euch: Wie muss das nachstehende einfache Testprogramm geändert werden, damit die im Unterprogramm geänderten Werte von x,y, und z an das Hauptprogramm übergeben werden und damit der zweite Ausdruck von x,y, und z 2,3,4 ergibt?

    Gruß
    heinz-georg187

    //Test Subroutinen
    #include <iostream>
    #include <math.h>
    using namespace std;
    float add (float , float , float ); // Funktionsprototyp
    float x=1;
    float y=1;
    float z=1;
    int main(){
    cout<<"\n"<<" x = "<< x;
    cout<<"\n"<<" y = "<< y;
    cout<< "\n"<<" z = "<< z;
    add(x,y,z);
    cout<< "\n"<<" x = "<< x;
    cout<< "\n"<<" y = "<< y;
    cout<< "\n"<<" z = "<< z;
    char response;
    std:cin >> response;
    return 0;
    }
    float add (float x,float y, float z) {
    x= x+1;
    y=y+2;
    z= z+3;
    cout<< "\n"<<" z = "<< z;

    }



  • Hallo und willkommen.

    Ich war mir selbst nicht ganz schlüssig was du meinst aber ich denke, du meinst Funktionen.

    Für dein Problem gibt es drei Lösungen:
    -Rückgabewerte
    -Call-By-Pointer
    -Call-By-Reference

    Wenn du drei Instanzen mit einem Funktionsaufruf ändern möchtest, musst du zu einem der beiden letzten greifen, es sei denn du machst dir einen eigenen Datentyp nur für die Funktion, was ein bisschen overkill wäre.

    Da Call-By-Pointer unnötige Nachteile im Vergleich zu Call-By-Reference hat, ist es klar was du am besten verwendest.



  • Nachtrag:
    1. Nutze C++-Code-Tags, das Lesen wird massiv vereinfacht.
    2. #include <math.h> ist nicht erlaubt, schreibe stattdessen <cmath> (obwohl du den Header hier gar nicht brauchst.
    3. Der Funktionsprototyp ist unnötig.
    4. Globale Variablen sind nicht schön.
    5. Wenn du einen Rückgabetyp deklarierst, solltest du auch etwas zurückgeben.
    6. Statt n = n + x; kannst du n += x; schreiben.
    7. Statt float hätte hier auch ein ganzzahliger Datentyp gereicht.
    8. Ich sehe keinen Sinn bei der Variable response .
    9. Die main -Funktion braucht kein explizites return 0; .

    Codebeispiel:

    #include <iostream> 
    void Add(float& x, float& y, float& z)
    {
        x += 1; 
        y += 2; 
        z += 3; 
        std::cout << '\n' << " z = " << z; 
    }
    int main()
    { 
        float x = 1;
        float y = 1;
        float z = 1;
        std::cout << '\n' << " x = " << x; 
        std::cout << '\n' << " y = " << y; 
        std::cout << '\n' << " z = " << z; 
        Add(x, y, z); 
        std::cout << '\n' << " x = " << x; 
        std::cout << '\n' << " y = " << y; 
        std::cout << '\n' << " z = " << z;
        char response; 
        std:cin >> response; 
    }
    


  • ...



  • Wieso

    Swordfish schrieb:

    friend point_3d_t add( point_3d_t lhs, point_3d_t rhs );
    

    statt

    friend point_3d_t operator+ (point_3d_t const& Lhs, point_3d_t const& Rhs);
    point_3d_t& operator+= (point_3d_t const& Rhs);
    

    ?


  • Mod

    MarcoYolo hat dir schon die technisch passenden Antworten gegeben. Eine weitere erwähnenswerte Möglichkeit wäre std::tuple (aus dem neuen Standard), insbesondere zusammen mit std::tie. Das sähe dann so aus:

    #include <tuple>
    #include <iostream>
    
    using namespace std;
    
    tuple<float, float, float> add(float x, float y, float z)
    {
      return make_tuple(x+1, y+2, z+3);
    }
    
    int main()
    {
      float x = 1, y = 2, z = 3;
      cout << "Vorher: x = " << x << " y = " << y << " z = " << z << '\n';
      tie(x,y,z) = add(x,y,z);
      cout << "Nachher: x = " << x << " y = " << y << " z = " << z << '\n';
    }
    

    Hier bietet es sich jedoch an, das Problem an sich besser zu modellieren. Deine x,y,z sollen allem Anschein nach mathematische 3D-Vektoren darstellen. Da bietet es sich doch an, diese als eigene Klasse zusammenzufassen und entsprechende Methoden zur Bearbeitung dieser Klasse anzubieten. Dies übersteigt deinen Kenntnisstand wahrscheinlich noch, aber man sollte es mal als Ausblick erwähnen, da es die "richtigere" Lösung wäre.



  • ...



  • Herzlichen Dank an MarcoYolo, Swordfish und Sepp für Eure Hilfe, die mir zugleich in Erinnerung ruft, was mir alles noch an Grundlagen fehlt. Ich stehe noch am Anfang meines Lernprozesses bei c++ (zunächst mit Hilfe des Buches von Helmut Erlenkötter). So bitte ich jetzt schon um Verständnis, dass ich Eure Hilfe wohl noch öfter in Anspruch nehmen muss.

    Zu meinem Hintergrund.: Ich war vor etwa 50 Jahren einigermaßen fit in Fortran 4. Mein erster Fortan-Kurs war 1967 an der University of Idaho. Dann hat mich mein beruflicher Werdegang relativ früh ins Management geführt, so dass ich das Programmieren anderen überlassen musste. Um mit meinen Kindern in den 80-ger Jahren einigermaßen mitzuhalten, habe ich für den Hausgebrauch Basic gelernt.

    Ich will jetzt als Renter mit 75 Jahren c++ lernen, um ein altes in jungen Jahren nicht zu Ende gebrachtes Projekt zu verwirklichen: die Berechnung des Bewegungsablaufes eines nur durch Schlitze gesteuerten pneumatischen Schlagbohrhammers. Dabei habe ich Vison, dies in einer Weise zu tun, von der man vor 50 Jahren noch nicht einmal träumen konnte: Die Visualisierung des Bewegungsablaufes und der sich ändernden Drücke über und unter dem Schlagkolben (z.B. Variation der Helligkeit einer Farbe) im Zeitlupentempo auf dem Bildschirm.

    Der Weg dahin ist noch lang, aber ich betrachte das ganze nicht nur als Hobby, sondern auch als ein wenig Gehirnjogging.

    Nun zu den einzelnen Beiträgen:

    Den Vorschlag von MarcoYolo habe ich verstanden und auch erfolgreich getestet. Allerdings musste ich die Zeile „using namespace std“ hinzufügen, damit das Ergebnis auf dem Bildschirm sichtbar war. Ich hatte früher Probleme, die Ergebnisse der im Buch von Helmut Erlenkötter ausgewiesenen Beispielprogramme auszudrucken. Im Forum fand ich dann den Rat, die oben genannte Zeile sowie die Zeilen
    char reponse;
    std:cin>>response;
    hinzuzufügen. Danach klappte es mit dem Ausdruck auf dem Bildschirm, wobei ich allerdings nicht weiss, was die Befehle konkret bewirken.

    Auch den Vorschlag von Swordfish konnte ich erfolgreich umsetzen. Für den Ergebnisausdruck war allerdings auch hier der Zusatz der vorab genannten Zeilen erforderlich. Zum Verständnis dieses Programmvorschlages muss ich mich aber erst noch mit dem Kapitel Pointer im Lehrbuch intensiv auseinandersetzen.

    Die Programmversion von Sepp konnte ich nicht kompilieren und erhielt eine Fehlermeldung. Ich vermute, dass mein altes Dev-C++ die Funktion tuple noch nicht kennt.

    Nochmals vielen Dank,

    heinz-georg187



  • Respekt Heinz-Georg,

    ich finde es bemerkenswert, dass du dir noch mal ein großes Ziel gesetzt hast, ohne Druck und nur aus eigenem Interesse.
    Viel Glück und Erfolg dabei!

    PS:
    Das Microsoft Visual Studio Express ist kostenlos erhältlich, man darf damit sogar kommerziell Software entwickeln. Solltest du mal einen Blick drauf werfen, damit hast du ein Front- und Backend aus einem Guss.



  • heinz-georg187 schrieb:

    Im Forum fand ich dann den Rat, die oben genannte Zeile sowie die Zeilen
    char reponse;
    std:cin>>response;
    hinzuzufügen. Danach klappte es mit dem Ausdruck auf dem Bildschirm, wobei ich allerdings nicht weiss, was die Befehle konkret bewirken.

    Du schreibst ein Konsolenprogramm, das via cout/printf etwas auf die Konsole schreibt. Normalerweise sollte man Konsolenprogramme auch aus einer Konsole starten. Du machst das jedoch nicht, sondern machst zum Beispiel einen Doppelklick auf die exe-Datei im Windows-Explorer. Windows erkennt, dass Du ein Konsolenprogramm starten willst, öffnet eine Konsole, führt das Programm aus, und wenn das Programm zu Ende gelaufen ist, schließt Windows die Konsole wieder. Deshalb siehst Du den Programmoutput nicht.

    Mit den beiden obigen Zeilen am Programmende verhinderst Du einfach, dass das Programm sofort zu Ende ist. Es wartet nun noch auf eine Eingabe, die es in die Variable response einliest und beendet sich erst dann (und schließt auch dann erst die Konsole).


Anmelden zum Antworten