2 variablen als funktions-rückgabewert ohne struct



  • hallo!

    ich hab hier ein kleines problem:
    ich möchte 2 variablen als rückgabe werte einer funktion an die main zurückgeben und zwar ohne sie in ein struct zu schreiben und das struct zurückzugeben.

    + ergänzung: wenn möglich bitte auch _ohne_ globale variablen...

    geht das irgendwie mit pointern?

    hier mal ein kleines code-beispiel:

    // blabla... includes...
    // ... prototypen...
    
    int main()
    {
      int variable1, variable2;
    
      funktion();  // funktionsaufruf
    
      printf("variable1=%i - variable2=%i", variable1, variable2); // die beiden variablen, die aus funktion() kommen anzeigen.
    
      return 0;
    }
    
    int funktion()
    {
      int eins=1, zwei=2; // die beiden variablen sollen in der main auch verfügbar sein
    
      return ???
    }
    

    [ Dieser Beitrag wurde am 20.10.2002 um 20:28 Uhr von root2 editiert. ]



  • benutz doch Pointer/Referenzen



  • hm 😉

    auf die idee bin ich ja auch schon gekommen aber als ziemlicher 'newbie' bin ich nicht allzu firm mit pointern/referenzen.

    wenn ich einen pointer als rückgabewert der funktion definiere kann ich ja auch wieder nur einen wert zurückgeben oder?

    root2



  • hi, so sollte es gehen kann dir auch noch ne variante mit zeigern schreiben wenn dir das nicht reicht....
    void funktion(int &a,int &b) // Referenzen
    {
    a = 10;
    b = 20;
    }
    int main(int argc, char* argv[])
    {
    int x = 0,y = 0;
    funktion(x,y);
    printf("%d %d",x,y);
    return 0;
    }



  • jo, so meinte ich das.

    du könntest auch ein Array zurückgeben, wenn es sich um den gleichen Variablen Typ handelt (wenn nicht geht das zwar auch via void* aber das ist sehr hässlich und fehleranfällig wegen den casts)



  • hm ich hab da noch ein paar fragen:

    void funktion(int &a,int &b) // &a ist die adresse von a, oder?
    {
    a = 10; // fehlt hier nicht ein "INT" oder ein "DOUBLE" ??
    b = 20; // hier ebenfalls?
    }       // ausserdem fehlt hier das "RETURN" komplett... die gibt nichts zurück oder?
    
    int main(int argc, char* argv[])
    {
    int x = 0,y = 0;
    funktion(x,y);        // ich rufe meine funktion _ohne_ parameter auf, sie liefert aber 2 werte zurück.
    printf("%d %d",x,y);  // ist das ein typecast nach double? x, y waren als INT definiert...
    return 0;
    }
    

    grüsse

    root2

    [ Dieser Beitrag wurde am 20.10.2002 um 21:00 Uhr von root2 editiert. ]



  • danke
    an die möglichkeit mit arrays hab ich garnicht gedacht 😉
    trotzdem komm ich nicht so ganz weiter... ich hab das programm mal verändert zu:

    root2

    // blabla... includes...
    // ... prototypen...
    
    int main()
    {
      int variablen[2]; // 'container' für die beiden rückgabewerte
    
      *variablen = * funktion();  // funktionsaufruf
    
    printf("variable1=%i - variable2=%i", variablen[0], variablen[1]); // die beiden variablen, die aus funktion() kommen anzeigen.
    
    return 0;
    }
    
    int * funktion()
    {
      int eins=1, zwei=2; // die beiden variablen sollen in der main auch verfügbar sein
      int variabel[2];
    
      variabel[0]=eins;
      variabel[1]=zwei;
    
    return variabel
    }
    

    die 1. variable zeigt er mir an, aber bei der 2. kommt nur müll (ich denke mal das ist die adresse der 2. aber nicht deren wert...)

    mach ich da noch was falsch?

    root2

    [ Dieser Beitrag wurde am 20.10.2002 um 21:48 Uhr von root2 editiert. ]



  • lass mal das dereferenzieren weg, also

    variablen = funktion();
    


  • klappt auch nicht 😞
    dann bekomm ich eine fehlermeldung:

    (C++ Error 54): Lvalue required

    ich hab mal in der hilfe des builders (c++ builder 5 enterprise) nachgeguckt. da schreiben sie ein lvalue wäre ein *p wert... also doch ein pointer, deswegen hab ich die variablen auch dereferenziert.
    die variante mit beiden * ist die einzige, die der builder frisst 😞

    root2

    [ Dieser Beitrag wurde am 20.10.2002 um 22:25 Uhr von root2 editiert. ]



  • Hätte nicht gedacht, dass kingruedi das nicht sieht. NAtürllich geht das so nicht, denn die Variable 'variabel' in der Funktion ist natürlich lokaler Art. Du hast 2 Möglichkeiten:

    1. Du erstellst vor Aufrufen der Funktion ein Array und übergibst dieses per Pointer:
    int main()
    {
       int array[2];
       funktion(array);
       printf("%d, %d", array[0], array[1]);
       return 0;
    }
    
    void funktion(int* v)
    {
       v[0] = 1;
       v[1] = 2;
    }
    
    1. Du erstellst das Array in der Funktion mit new und gibst es zurück:
    int main()
    {
       int* array = funktion();
       printf("%d, %d", array[0], array[1]);
       delete[] array;
       return 0;
    }
    
    int* funktion()
    {
       int* v = new int[2];
       v[0] = 1;
       v[1] = 2;
       return v;
    }
    

    [EDIT]
    Das Problem in deinem Code ist auch deine vorgenommene Dereferenzierung. Wenn du geschrieben hättest

    int* Variable = funktion();
    

    dann hätte es vielleicht geklappt. Aber gut, dass du's so nicht gemacht hast, denn dann hätteste gedacht, dass es richtig ist - ist es aber eben nicht, da ja eine Adresse einer Speicherstelle auf dem Stack zurückgegeben wird, die nach Ablauf der Funktion wieder freigegeben wird. D.h., da könnte u.U. total unbrauchbarer Mist drinne stehen.
    [/EDIT]

    [ Dieser Beitrag wurde am 21.10.2002 um 02:17 Uhr von WebFritzi editiert. ]



  • Es geht wie gesagt auch mit Referenzen. Ein Beispiel wurde auch schon gezeigt. Das Geheimnis ist folgendes: Wenn du eine Funktion aufrufst wie

    float v = 1.;
    funktionCBV(v);
    

    dann wird das v im Speicher kopiert, und die Funktion benutzt diesen kopierten Wert. CBV steht für 'Call by Value'. Du kannst aber auch direkt die Speicherstelle der Variablen v übergeben. Das geht dann per Pointer (wie im vorigen Beitrag beschrieben). Diese Verfahren nenn sich 'Call By Reference' (obwohl es dabei keine Referenzen gibt). Eine andere Möglichkeit besteht darin, ohne Pointer zu arbeiten, die Funktion wie eine CBV-Funktion zu deklarieren, hinter die Typen der Variablen aber noch ein '&' zu stellen:

    void funktion(float& v);
    

    Dann kann man die Funktion wie oben aufrufen:

    float v = 1.;
    funktion(v);
    

    Der Unterschied zu oben ist, dass hier mit dem gleichen Speicher gearbeitet wird, der übergeben wird. Lass die Funktion z.B. so aussehen:

    void funktion(float& v)
    {
       v = v * 2;
    }
    

    Dann wird nach einem Aufruf wie oben v=2 sein, weil das v in der Funktion praktisch das gleiche ist wie das v im Aufruf.
    Hm, ich hoffe, ich habe die richtigen Worte gefunden. Irgendwie kann ich nicht erklären, glaube ich... *gräm*



  • @root2: Ich würde am ehesten die referenzen nehmen. Es ist eigentlich am einfachsten so.
    Um deine Verwirrung eventuell z klären: Wenn du eh schon die VAriablen veränderst, brauchst du auch kein return. Die Referenzen werden ja so schon verändert (eigentlich stimmt auch das nicht. [in 2 Monaten weisst du sicher auch wieso. *G*]) .



  • @WebFritzi
    oh, hast recht. Ich hab es wirklich übersehen. Naja man merkt doch, dass man 8 Tage weg war und nicht proggen konnte 😉



  • edit: klappt doch ganz gut 😉
    danke an alle 😉

    root2

    [ Dieser Beitrag wurde am 22.10.2002 um 07:47 Uhr von root2 editiert. ]


Anmelden zum Antworten