Funktion: Rückgabe von Arrays



  • Hallo. Ich bin ein Anfänger was Programmierung und C++ angeht und bin gerade dabei zu lernen, wie man mittels Funktionen Arrays mittels Pointern zurückgibt. Dazu habe ich versucht eine Funktion zu schreiben, die ein Array mit einem gewünschten Faktor durchmultipliziert. Es scheint alles bis auf die korrekte Rückgabe zu funktionieren und ich check nicht wirklich warum. Hier ist der dazugehörige Code:

    #include <iostream>
    #include <string>
    #include <sstream>
    
    using namespace std;
    
    
    int *MultiArray(int arr[3], int factor)
    {
        int result[3];
        for(int i=0; i<3; i++)
        {
            result[i] = factor*arr[i];
        }
        return result;
    }
    
    int main()
    {
    int a[3];
    int f;
    int *p;
    for(int i=0; i<3; i++)
        {
            cout << "Bitte den " << i+1 << ". Wert des Arrays eingeben:" << endl;
            cin >> a[i];
        }
    cout << "Bitte den Faktor f eingeben, mit dem multipliziert werden soll:" << endl;
    cin >> f;
    p = MultiArray(a, f);
    for(int i=0; i<3; i++)
    {
    cout << "Wert " << i+1 << " des Ergebnis-Arrays: ";
    cout << *(p+i) << endl;
    }
    return 0;
    }
    
    

    Danke schonmal für die Hilfe.



  • @CPP-Knäblein benutze std::vector oder std::array, nicht C-Style arrays.



  • bin gerade dabei zu lernen, wie man mittels Funktionen Arrays mittels Pointern zurückgibt.

    Warum? Nimm std::vector, dann funktioniert dein Code wie gewünscht!

    Der Grund, dass dein Code nicht funktioniert: das int result[3] ist eine Variable, die nur INNERHALB der Funktion MultiArray gültig ist. Du returnst aber einen Pointer auf diese nur innerhalb der Funktion gültige Variable. Daher darfst du danach nicht mehr auf sie zugreifen.

    Du slltest auch Warnungen beim Compilieren einschalten, dann sagt dir der Compiler schon genau das:

    forum.cpp: In function ‘int* MultiArray(int*, int)’:
    forum.cpp:10:9: warning: address of local variable ‘result’ returned [-Wreturn-local-addr]
         int result[3];
             ^~~~~~
    


  • Okay. Vielen Dank schonmal. Das versuche ich gleich mal. Muss ich die Größe der Arrays auch in Klammern dahinter schreiben? Und was ist denn der Unterschied zwischen den Schreibweisen? Ich würde gerne verstehen, watum es auf die Weise funktioniert und auf die andere nicht...



  • @CPP-Knäblein Der Unterschied ist, dass ein std::vector seinen Speicher intern automatisch verwaltet. Du musst dich also um nichts kümmern. Der vector weiß auch selbst, wie groß er ist. Du kannst die Größe am Anfang angeben oder nacheinander mit push_back Elemente einfügen.

    Ein Array hat immer eine festgelegte Größe. Wenn du ein Array an eine Funktion übergibst oder aus einer Funktion zurückgibt, übergibst du (mit int*) nur einen Pointer auf das erste Element und keine Information, wie groß das Array ist oder wem der Speicher gehört.

    Bitte verabschiede dich von Arrays für den Standardgebrauch. Nimm by default immer vector. Dann brauchst du auch keinen einzigen Stern in deinem Programm.

    Und was ist denn der Unterschied zwischen den Schreibweisen?

    Zwischen welchen Schreibweisen genau?



  • Könntest du mir anhand des obigen Beispiels vielleicht mal zeigen, wie man dieses Array richtig initialisiert? Ich würde das gerne mal korrekt sehen, damit ich das in Zukunft besser verwenden kann.

    @wob sagte in Funktion: Rückgabe von Arrays:

    Zwischen welchen Schreibweisen genau?

    Hat sich quasi schon in deiner Antwort ergeben, danke.



  • Ah und sollte ich std::array dann auch in der Funktionsklammer verwenden?



  • @CPP-Knäblein sagte in Funktion: Rückgabe von Arrays:

    Ah und sollte ich std::array dann auch in der Funktionsklammer verwenden?

    Nein, std::vector sollst du verwenden! Nicht std::array. Mit std::array bist du auf eine feste Anzahl Elemente beschränkt. Und Funktionen wir das MultiplyArray sollten ja wohl mit verschieden vielen Elementen klarkommen.

    Wie wäre es so - ich habe mich dicht an dein Programm gehalten, habe aber die Variablen ausgeschrieben, also f -> faktor und statt multiArray multiply (denn multi könnte auch multidimensional oder multivitamin oder irgendwas anderes sein und die 3 Buchstaben "ply" sind doch nicht schlimm zu tippen?)
    Außerdem findet sich die Größe "3" für 3 Zahlen jetzt nur noch an genau einer Stelle. Du kannst also leicht auch mal 10 oder 100 Zahlen multiplizieren.

    #include <iostream>
    #include <vector>
    
    std::vector<int> multiply_array(std::vector<int> arr, int factor)
    {
        // arr ist durch pass-by-value schon kopiert
        for (auto &value : arr)
        {
            value *= factor;
        }
        return arr;
    }
    
    int main()
    {
        std::vector<int> inArray;
        for (int i = 0; i < 3; ++i)
        {
            std::cout << "Bitte den " << i + 1 << ". Wert des Arrays eingeben:" << std::endl;
            int wert;
            std::cin >> wert;
            inArray.push_back(wert);
        }
        std::cout << "Bitte den Faktor f eingeben, mit dem multipliziert werden soll:" << std::endl;
        int faktor;
        std::cin >> faktor;
        auto produktArray = multiply_array(inArray, faktor);
        for (size_t i = 0; i < produktArray.size(); ++i)
        {
            std::cout << "Wert " << i+1 << " des Ergebnis-Arrays: ";
            std::cout << produktArray[i] << std::endl;
        }
        return 0;
    }
    

    PS: ich bin eigentlich kein großer Fan des std::endl, wenn es \n auch tun würde. Habs jetzt aber mal so gelasen.



  • Ah vielen dank. Ich denke den Großteil verstanden zu haben. Nur was "auto &value : arr) in dem for zu suchen hat und was es bedeutet checke ich leider nicht.



  • @CPP-Knäblein Siehe https://en.cppreference.com/w/cpp/language/range-for

    Einfach über alle Elemente des Vectors loopen - Vorteil: kein Index nötig, dadurch kannst du dich auch nicht verzählen.

    Ich glaube, du musst dir mal irgendwie aktuelles Lehrmaterial besorgen.



  • @CPP-Knäblein Dein Programm ist „C mit cout“.
    Das ist kein modernes C++.


Anmelden zum Antworten