Rückgabe eines pointers auf array



  • @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.


  • Mod

    @john-0 sagte in Rückgabe eines pointers auf array:

    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.

    Ja eben. Deswegen erklär ich ja, dass das noch nie in irgendeiner Sprache jemals richtig war. Aber das ist halt das typische Pattern von Leuten, die vor 50 Jahren mal mit Fortran oder Pascal im Eigenstudium angefangen haben; niemals Feedback von guten Programmierern hatten; und nun meinen, sie könnten C++ lehren, indem sie BEGIN durch { ersetzten.



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

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

    Again.

    Und: Eigentlich hasse ich es irgendwas von new T[] oder std::*alloc() zurückgegebenes als Array zu bezeichnen. Daher würde ich betreffendem Dozenten die Aufgabe zurückwerfen und sagen daß was er fordert nicht möglich ist. Problem solved.



  • @SeppJ

    Ziemlich ernüchternd zu lesen, dass einem im Studium veraltete und zudem falsche Inhalte beigebracht werden.
    Danke für eure Lösungsansätze.
    Könnt ihr mir dann seriöse Quellen zum Lernen von sinnvollem C++ empfehlen?


  • Mod

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

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

    Bitte auf höherem Niveau mitdenken. Es geht nicht darum, dass der String terminiert ist, sondern darum, wie strcat grundlegend funktioniert und vor allem, was nicht seine Aufgabe ist und was es deswegen nicht tut. Es nimmt Information entgegen, welche Daten aneinander gehängt werden, und es nimmt Information entgegen, wo diese hin sollen. Es ist macht kein Ressourcenhandling! Es gibt keine statischen Ressourcen zurück! Es macht seine eine Aufgabe und macht diese Aufgabe gut und sehr strikt nach den Regeln und best practices der Sprache C.



  • @SeppJ Ok. 1:0.


  • Mod

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

    Könnt ihr mir dann seriöse Quellen zum Lernen von sinnvollem C++ empfehlen?

    Der Standardlink:
    https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list

    Aktiv zu meiden:

    • Es sind keine guten Videotutorials bekannt.
    • Alle Bücher, wo vollständiger ('komplett', 'von A bis Z'), schneller ('in 21 Tagen', und/oder einfacher ('für Dummies') Lernerfolg versprochen wird.
    • Leider sieht es auch bezüglich der deutschen Sprache recht düster aus. Wer gut genug ist, ein tolles Buch zu schreiben, der schreibt auch auf Englisch. Entweder, um ein größeres Publikum zu erreichen, und oft auch weil sie einfach US-Amerikaner sind.


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

    Es macht seine eine Aufgabe und macht diese Aufgabe gut und sehr strikt nach den Regeln und best practices der Sprache C.

    Nicht wirklich, es macht den Dest String radikal platt, ob für den Source String Platz vorhanden ist oder nicht. Solche Funktionen haben den schlechten Ruf von C begründet. Nur noch gets übertrifft das.


  • Mod

    @john-0 sagte in Rückgabe eines pointers auf array:

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

    Es macht seine eine Aufgabe und macht diese Aufgabe gut und sehr strikt nach den Regeln und best practices der Sprache C.

    Nicht wirklich, es macht den Dest String radikal platt, ob für den Source String Platz vorhanden ist oder nicht. Solche Funktionen haben den schlechten Ruf von C begründet. Nur noch gets übertrifft das.

    Es gibt halt Leute, die die Prinzipien von C verstehen, und solche, dies nicht tun. Du verwechselst auf jeden Fall "es ist nach den Prinzipien gemacht, die für C vorgesehen sind" mit "ich halte die Prinzipien von C für gut".


Anmelden zum Antworten