Rückgabe eines pointers auf array



  • Hallo, ich habe die Aufgabe zwei Arrays in einer Funktion zu einem neuen Array zu verschmelzen.
    Der Return- Wert soll ein Zeiger auf das neue Array sein.
    Leider finde ich keine zu meinem Problem passenden Beiträge im Internet. Das kann natürlich an meinen Suchbegriffen liegen.
    Meine Frage ist wie muss die Funktion aussehen um einen Pointer zurückzugeben?
    Müssen alle Input -Parameter selbst Pointer sein?
    Hier ist mein bisheriger Code:

    #include <iostream>
    
    using namespace std;
    
    int *fuse(int array1, int array2, int l1, int l2, int p);
    
    int main()
    {
        int pos = 0;
        int* fArr;
        int arr1[] = {7, 3, 5, 9, 6, 2};
        int arr2[] = {9, 1, 4, 1, 6, 8, 3, 5};
        int length1 = sizeof(arr1)/ sizeof(int);
        int length2 = sizeof(arr2)/ sizeof(int);
        cout << "Where do you want to fuse? Name position from 'array1'" << endl;
        cin >> pos;
        fArr = fuse(arr1, arr2, length1, length1, pos);
        
        return 0;
    }
    
    int *fuse(int array1, int array2, int l1, int l2, int p)
    {
       static int *arr3 = new int[l1 + l2];
        
        for(int i =0;i< p-1; i++)
        {
            arr3[i] = array1[i];
        }
        for(int i =p-1;i< p+(l2-1); i++)
        {
            static int j=0;
            arr3[i] = array2[j];
            j++;
        }
        for(int i = p+(l2-1);i<(l1+l2); i++)
        {
            static int k = p-1;
            arr3[i] = array1[k];
            k++;
        }
        return arr3;
        
    }
    

    Gerne auch Kritik und Verbesserungsvorschläge was Programmierstil angeht.



  • @onzeq
    warum benutzt du in der funktion statische variablen? bist du sicher, dass die funktion überhaupt arrays übernimmt? hast du mal was davon gehört, dass zu jedem new immer ein delete gehört?

    wenn eine funktion ein array zurückgeben soll, macht man das im allgemeinen, indem man die beiden klammern hinter den datentyp schreibt. also z.b. double[] MeineFunktion()



  • Schonungslose, offene Kritik:
    Totaler Mist! Nimm´s nicht persönlich, vermutlich fängst du gerade an, C++ zu programmieren, aber so macht man´s nicht. Ist das eine Aufgabe, die du lösen musst, oder darfst du machen, was du möchtest?


  • Mod

    Wichtige Frage: Willst du C++ oder C machen? Derzeit ist das C mit cout. In C++ würde man das grundsätzlich gaaaaanz anders machen. Eigentlich würde sich die Frage in C++ überhaupt gar nicht stellen. In C würde man es zwar auch ganz anders machen, aber zumindest würden ähnliche Sprachmittel benutzt werden, wie in deinem Beispiel, bloß anders kombiniert. Mischen solltest du aber auf gar keinen Fall.



  • @Wade1234
    Die statischen Variablen nutze ich damit die Zählvariable nicht bei jedem Sprung in die Schleife neu initialisiert wird sondern den Wert behält. Wusste keine bessere Möglichkeit. Ist es gefährlich dafür statische Variablen zu nutzen?

    Muss ich delete auch nutzen wenn ich ich den array nicht löschen will? Den will ich ja behalten.

    Der Rückgabewert soll nicht das Array selbst sein sondern ein Pointer auf das Array



  • @DocShoe
    ist eine Praktika Aufgabe aus der Info Vorlesung im Mechatronikstudium.
    Dachte ich mir schon dass das Käse ist, deswegen bin ich hier.



  • @onzeq Wie lautet die Aufgabe (Wortlaut) und welche Sprache? C oder C++?



  • @SeppJ
    Vorlesung ist zu C++ und die Aufgabe auch.
    Ich habe nur eine Aufgabenstellung und versuche diese umzusetzen.
    Was vermische ich und wie würde man im Allgemeinen vorgehen?



  • @onzeq sagte in Rückgabe eines pointers auf array:

    Ich habe nur eine Aufgabenstellung und versuche diese umzusetzen.

    @Swordfish sagte in Rückgabe eines pointers auf array:

    Wie lautet die Aufgabe (Wortlaut)



  • @Swordfish
    Schreiben Sie eine Funktion fuse, die zwei int-Arrays beliebiger Länge „verschweißt“. Sie reserviert zu diesem Zweck ein dynamisches Array, das beide int-Arrays aufnehmen kann. Dann kopiert sie die Elemente aus beiden int-Arrays in das neue Array und zwar so:
    "Bild"

    • Zunächst werden die Elemente des ersten Arrays bis zu einer in main einzulesenden, vorgegebenen Position eingefügt.
    • Dann wird das zweite Array eingefügt.
    • Zuletzt wird der Rest des ersten Arrays angehängt.

    Argumente: Die beiden int-Arrays, ihre Länge und die Position, bei der „verschweißt“ wird.

    Return-Wert: Ein Zeiger auf das neue Array. Ist die angegebene Position < 0 oder größer als die Länge des ersten Arrays, soll ein Zeiger auf nullptr zurückgegeben werden.

    a) Testen Sie ihre Funktion in einem kleinen Programm mit im Quellcode von main fest vorgegebenen Arrays und einer vom Benutzer definierten Verschweiß-Stelle. Geben Sie die beiden ursprünglichen Arrays, das verschweißte Array, deren jeweilige Längen sowie die Verschweißstelle formatiert im Hauptprogramm aus. Achten Sie im „Fehlerfall“ auf verständliche Meldungen.



  • @onzeq

    wie bei jedem sprung in die schleife? also mal angenommen, du würdest die funktion jetzt mehrmals aufrufen, dann hättest du da doch immer den kram aus dem vorherigen aufruf drin. das hieße z.b. dass du dann außerhalb des eigentlichen speicherbereichs bist, weil j z.b. nur beim 1. aufruf auf 0 gesetzt wird. also wenn ich mich jetzt nicht irre.

    ja wenn du new verwendest, musst du auch immer delete verwenden. notfalls am programmende.

    also wenn du ein array namens int array[10] hast, dann ist array doch quasi der pointer (unglücklich formuliert). der sinn, wirklich einen zeiger zurückzugeben erschließt sich mir nicht so ganz. aber das müsste dann datentyp*[] sein.



  • @Wade1234 sagte in Rückgabe eines pointers auf array:

    wenn eine funktion ein array zurückgeben soll, macht man das im allgemeinen, indem man die beiden klammern hinter den datentyp schreibt. also z.b. double[] MeineFunktion()

    @Wade1234: Kannst du überhaupt C++? Denn double[] MeineFunktion() ergibt einen Kompilerfehler: Ideone-Code.
    Aber lass dich nicht von der Fehlermeldung verwirren: C++17: structured bindings sind ein ganz anderes Sprachkonstrukt.

    Es muß, wenn überhaupt, dann double* MeineFunktion() heißen.


  • Mod

    @onzeq sagte in Rückgabe eines pointers auf array:

    @SeppJ
    Vorlesung ist zu C++ und die Aufgabe auch.

    Nein, ist sie nicht. Vielleicht sagt man euch, dass das C++ wäre, aber es ist (schlechtes) Fortran mit C-Schlüsselwörtern und ein paar C++-Hilfsfunktionen. Wenn du nur irgendwie kannst, lass die Vorlesung fallen. Dort wirst du dir nur lauter schlechte Gewohnheiten holen, die du nicht mehr so einfach los wirst.

    Was vermische ich und wie würde man im Allgemeinen vorgehen?

    In C++? So ungefähr:

    #include <iostream>
    #include <vector>
    #include <iterator>
    
    using namespace std;
    
    template <typename Seq1, typename Seq2, typename OutputIterator> 
    void append(const Seq1 &seq1, const Seq2 &seq2, OutputIterator it)
    {
    	for (auto a: seq1)
    		*it = a;
    	for (auto a: seq2)
    		*it = a;
    }
    
    int main() 
    {
    	vector<int> first = {1,2,3}, second = {4,5,6,7}, destination;
    	append(first, second, back_inserter(destination));
    	for (auto i: destination)
    		cout << i << ' ';
    }
    

    https://ideone.com/9kJhAg

    Was siehst du daran?

    • Es kommen keine der Elemente aus der Aufgabenstellung vor. Keine Pointer, keine Speicherallokation, keine nullptr. Denn was in der Aufgabenstellung verlangt wird, ist nicht wirklich, wie man C++ schreibt.
    • Du verstehst kein Wort und hast noch nix davon jemals gesehen. Das liegt daran, dass die Sprachelemente, die du gelernt hast, auschließlich C sind, außer cout.
    • Das ganze ist trotzdem relativ verständlich, selbst wenn man noch nie von vector, template, auto, etc. gehört hat, oder? Es sollte relativ klar sein, was hier in welcher Reihenfolge passiert, und wie alles zusammen passt. Das liegt daran, dass dein Kurs dir eine Denkweise beigebracht hat, wie sie ein schlechter Möchtegern-Fortan-Hacker 1960 gehabt hat, nicht wie man heutzutage Computer programmiert. Weder in C++ noch in C (und auch nicht in modernem Fortran).


  • Was von dem Sourcecode ist denn vorgegeben und was hast du davon geschrieben? Mich beschleicht das Gefühl, dann dein Prof C mit cout unterrichtet, dass wäre leider nicht das erste mal, dass wir sowas hier im Forum sehen.

    In c++ wäre die Struktur für ein dynamisches Array ein std::vector und für ein statische Array ein std::array. Wenn man etwas bis zu einer bestimmten Position umkopieren möchte, würde man das wahrscheinlich über Iteratoren lösen.

    Edit: SeppJ hat wärend ich geschrieben habe, bereits Code geschrieben, der Zeigt, wie man das in C++ lösen könnte



  • @onzeq sagte in Rückgabe eines pointers auf array:

    @Swordfish
    Schreiben Sie eine Funktion fuse, [...]

    Die Aufgabenstellung ist ganz großer Mist. Wie @SeppJ sage: Fernhalten und wegwerfen (notfalls auch den Dozenten).

    C++17:

    #include <cstddef>    // std::size_t
    #include <iterator>   // std::size<>()
    #include <iostream>   // std::cin, std::cout, std::cerr
    #include <algorithm>  // std::copy_n<>()
    
    int* fuse(int const * const first_array,  std::size_t const first_array_length,
              int const * const second_array, std::size_t const second_array_length, long long position)
    {
    	if (position < 0 || position > first_array_length)
    		return nullptr;
    
    	int *result { new int[first_array_length + second_array_length] };
    
    	std::copy_n(first_array, position, result);
    	std::copy_n(second_array, second_array_length, result + position);
    	std::copy_n(first_array + position, first_array_length - position, result + position + second_array_length);
    
    	return result;
    }
    
    int main()
    {
    	long long position;
    	if (!(std::cin >> position)) {
    		std::cerr << "Input error!:(\n\n";
    		return EXIT_FAILURE;
    	}
    
    	int a[] { 1, 2, 3, 4, 8, 9, 10 };
    	int b[] { 5, 6, 7 };
    
    	int *c;
    	try {
    		c = fuse(a, std::size(a), b, std::size(b), position);
    	}
    	catch (std::bad_alloc) {
    		std::cerr << "Not enough memory :(\n\n";
    		return EXIT_FAILURE;
    	}
    
    	if (!c) {
    		std::cerr << "Entered position < 0 or > size of first array (" << std::size(a) << ") :(\n\n";
    		return EXIT_FAILURE;
    	}
    
    	for (std::size_t i {}; i < std::size(a) + std::size(b); ++i)
    		std::cout << c[i] << ' ';
    	std::cout.put('\n');
    
    	delete[] c;
    }
    
    

    // edit: nicht nachmachen. ist gaga.

    @onzeq sagte in Rückgabe eines pointers auf array:

    Geben Sie die beiden ursprünglichen Arrays, das verschweißte Array, deren jeweilige Längen sowie die Verschweißstelle formatiert im Hauptprogramm aus.

    Fehlt. Bitte selber machen.



  • @Th69 sagte in Rückgabe eines pointers auf array:

    @Wade1234 sagte in Rückgabe eines pointers auf array:

    wenn eine funktion ein array zurückgeben soll, macht man das im allgemeinen, indem man die beiden klammern hinter den datentyp schreibt. also z.b. double[] MeineFunktion()

    @Wade1234: Kannst du überhaupt C++? Denn double[] MeineFunktion() ergibt einen Kompilerfehler: Ideone-Code.

    kommt darauf an, was du unter "c++ können" verstehst.

    Aber lass dich nicht von der Fehlermeldung verwirren: C++17: structured bindings sind ein ganz anderes Sprachkonstrukt.

    Es muß, wenn überhaupt, dann double* MeineFunktion() heißen.

    das wäre die lösung, wenn man das array selbst zurück gibt, aber die aufgabe verlangt doch einen zeiger auf ein array, oder nicht?



  • @Wade1234 sagte in Rückgabe eines pointers auf array:

    ...
    das wäre die lösung, wenn man das array selbst zurück gibt, aber die aufgabe verlangt doch einen zeiger auf ein array, oder nicht?

    ?!?


  • Mod

    @Wade1234 sagte in Rückgabe eines pointers auf array:

    das wäre die lösung, wenn man das array selbst zurück gibt, aber die aufgabe verlangt doch einen zeiger auf ein array, oder nicht?

    Das ist halt einfach nur Arghhhh! In keiner Sprache, weder C, noch C++, noch Fortran, war es je korrekt, einen Handler auf eine dynamische Ressource aus einer Funktion zurück zu geben (außer aus der Funktion zur Anforderung derselben). Die einzigen Leute, die so etwas machen, sind die, die überhaupt keine Ahnung von irgendwelcher Programmstruktur haben, und ihr Wissen leider viel zu oft an Schulen weitergeben. Das ist ganz unabhängig von der Sprache. C mit cout könnte man ja sogar verkraften, wenn es wenigstens gutes, dogmatisches C wäre. Aber die Leute, die C mit cout lehren, machen halt auch immer solche Bockmistfunktionen wie diese hier. Das kann man gar nicht korrekt lösen so.

    Für eine korrekte, dogmatische C-Lösung schaue man sich strcat an. So hat die Signatur einer Funktion auszusehen, die zwei Folgen aneinander hängt! Am besten dazu auch mal das K&R-Buch lesen, wo viele der C-Stringfunktionen hergeleitet werden und erklärt wird, wieso das gut ist, das so zu machen.



  • @SeppJ sagte in Rückgabe eines pointers auf array:

    Das liegt daran, dass dein Kurs dir eine Denkweise beigebracht hat, wie sie ein schlechter Möchtegern-Fortan-Hacker 1960 gehabt hat, nicht wie man heutzutage Computer programmiert. Weder in C++ noch in C (und auch nicht in modernem Fortran).

    Das hat mit Fortran nichts zu tun, da bei altem Fortran überhaupt keine dynamischen Arrays möglich waren. D.h. die Aufgabestellung ergibt in Fortran77 oder älter keinerlei Sinn.



  • @SeppJ sagte in Rückgabe eines pointers auf array:

    Für eine korrekte, dogmatische C-Lösung schaue man sich strcat an. So hat die Signatur einer Funktion auszusehen, die zwei Folgen aneinander hängt! Am besten dazu auch mal das K&R-Buch lesen, wo viele der C-Stringfunktionen hergeleitet werden und erklärt wird, wieso das gut ist, das so zu machen.

    Wie terminierst Du ein Array of int in C? ernstgemeint.
    Ich glaube ich würde INT_MIN dafür wegwerfen. Fairerweise.


Anmelden zum Antworten