Wie 3 Werte an eine Funktion zurückgeben?
-
Hallo liebe Forummitglieder,
wir sollen für die Vorlesung Algorithmen & Datenstrukturen das "Sieb des Eratosthenes" in C++ implementieren. Folgende Bedingungen sind Voraussetzung:
*die Anzahl der Primzahlen und der Streichungen müssen ausgegeben werden
*Bibliotheksfunktionen dürfen nicht benutzt werden (auch cout nicht!!)Ich habe den Code soweit fertig. Mit cout (als Test) gibt das Programm alles prima aus. Wie kann ich aber die Werte von i (will ich aus persönlichem Interesse ausgeben), cnt_primanz und cnt_gestrichen
an die Funktion sieb() zurückgeben? Kann mir jemand von euch helfen?Hier der Code:
unsigned int sieb(unsigned int n); unsigned int sieb(unsigned int n) { bool zahl[n]; unsigned int cnt_gestrichen = 0; unsigned int cnt_primanz = 0; for (unsigned int i = 2; i < n; ++i) { if (!zahl[i]) { return i; cnt_primanz++; //Alle Nicht-Primzahlen werden gestrichen for (unsigned int j = i*i; j < n; j +=i) { zahl[j] = true; cnt_gestrichen++; } } } return 0; } int main(void) { const unsigned int n = 8; sieb(n); return 0; }Bisher gibt er mit der return-Variante nichts aus.
Grüße
kakashi
-
Naja, vielleicht kommst du auf die geniale Idee, eine Struktur (oder Klasse mit entsprechenden Methoden) a la
struct meins { unsigned erste, zweite, dritteVariable; }; meins func() { return {1, 2, 3}; }zu machen..

-
Hacker schrieb:
Naja, vielleicht kommst du auf die geniale Idee, eine Struktur (oder Klasse mit entsprechenden Methoden) a la
struct meins { unsigned erste, zweite, dritteVariable; }; meins func() { return {1, 2, 3}; }zu machen..

Aus seinem Beitrag geht doch eigentlich hervor, dass er gerade erst anfängt, C++ zu lernen. Darum:1. Ich glaube nicht, dass er sich bis jetzt schon mit Klassen befasst hat.
2. Dein C++11 Beispiel bringt ihm wahrscheinlich gar nichts, da er es wohl nicht kompilieren kann und überhaupt nicht weiß wieso.
3. Es scheint wohl so, als ob er sich gerade mit Grundlagen wie Schleifen und Funktionen auseinandersetzt, darum wäre der logische Lösungsansatz wohl Referenzen.Hallo kakashi83,
du suchst also praktisch das hier:// Lass den Prototypen weg, er ist total unnötig. // Mittels Referenzen kannst du eine beliebige Anzahl von "Rückgabeparametern" (sogenannte out parameter) haben. void sieb(unsigned n, unsigned* primzahlen, unsigned& cnt_gestrichen, unsigned& cnt_primanz) { bool* zahl = new bool[n]; // Die Größe eines Arrays muss immer zur Compiletime feststehen. Hier steht n aber erst zur Laufzeit fest, darum geht es nicht. Darum: Speicher dynamisch anfordern. // (Falls es bei dir docht geht, solltest du deinen Compiler wechseln) for(unsigned i=2; i<n; ++i) zahl[i] = false; for(unsigned i=2, index=0; i<n; ++i) { if( zahl[i]==false ) { primzahlen[index++] = i; ++cnt_primanz; for(unsigned j=i*i; j<n; j+=i) { zahl[j] = true; ++cnt_gestrichen; } } } delete[] zahl; // Du hast Speicher dynamisch angefordert, also musst du ihn auch selbst wieder freigeben. } int main() { const unsigned n = 8; // Das int kannst du weglassen, da nur unsigned die Kurzschreibwesie für unsigned int ist. unsigned primzahlen[n] = {};// ok, da n const ist. unsigned cnt_gestrichen = 0; unsigned cnt_primanz = 0; sieb(n,primzahlen,cnt_gestrichen,cnt_primanz); cout << "n = " << n << '\n'; cout << "cnt_gestrichen = " << cnt_gestrichen << '\n'; cout << "cnt_primanz = " << cnt_primanz << '\n'; cout << "primzahlen = "; for(unsigned i=0; i<cnt_primanz; ++i) { cout << primzahlen[i] << ", "; // Also cout brauchst du schon, wie willst du sonst bitte eine Ausgabe machen? } }
-
Mich würde allerdings auch mal interessieren, wie du es ausgeben sollst, wenn du keine bibliotheksfunktionen nutzen darfst, auch cout nicht.
ohne cout bleibt ja nur noch printf - wäre zwar dämlich, aber scheint ja an manchen unis keine rolle zu spielen... dummerweise ist es aber erst recht ne bibliotheksfunktion.
frag mal bitte deinen lehrer/prof/übungsleiter und schreib mal, was er antwortet.
deine frage an sich sollte ja von gugelmoser ausreichend beantwortet sein?!bb
-
Wieso benutzt du C-Arrays für dynamische Speicheranforderung? Wär doch viel einfacher mit z.B. einem vector o.ä.?
unsigned primzahlen[n] = {};// ok, da n const ist.Und nein, nicht OK wenn
nconstist, es müsste schonconstexprsein... seit C99 ist das aber sowieso im Standard (das es auch mit normalen Variablen geht, siehe hier).
-
Hacker schrieb:
seit C99 ist das aber sowieso im Standard
Wir programmieren hier aber C++, wo VLAs nach wie vor verboten sind.
Der Code beweist gar nichts, es handelt sich um eine g++-spezifische Compilererweiterung und nicht um Standard-C++.
-
Liebe Forummitglieder,
ich habe meinem Dozenten nochmal eine Email zu diesem Problem geschrieben. Mal sehen, was er dazu schreibt.
Ich danke euch für eure Beiträge und werde meinen Code nochmal überarbeiten. Mit cout wäre das Ganze kein Problem, ohne ist es jedoch sehr umständlich.
Grüße
Kakashi
-
Hacker schrieb:
Wieso benutzt du C-Arrays für dynamische Speicheranforderung? Wär doch viel einfacher mit z.B. einem vector o.ä.?
kakashi83 schrieb:
*Bibliotheksfunktionen dürfen nicht benutzt werden
Hacker schrieb:
Und nein, nicht OK wenn
nconstist, es müsste schonconstexprsein.Doch, das ist genau richitg so. Die Größe eines Arrays muss ein konstanter Ausdruck sein und das ist
n, da es const-spezifiziert ist und mit einem konstanten Ausdruck initialisiert wurde.
-
Gugelmoser schrieb:
Doch, das ist genau richitg so. Die Größe eines Arrays muss ein konstanter Ausdruck sein und das ist
n, da es const-spezifiziert ist und mit einem konstanten Ausdruck initialisiert wurde.const hat mit konstanten Ausdrücken erstmal nichts zu tun. Nicht alles, was const ist, ist auch ein konstanter Ausdruck.
int i = 42; int const j = i; // const, aber kein konstanter AusdruckDa im oben gegebenen Beispiel n ein konstanter Ausdruck ist, funktioniert es.
-
Gugelmoser schrieb:
da es const-spezifiziert ist und mit einem konstanten Ausdruck initialisiert wurde.
Bei
constexprist immer garantiert, dass ihm ein konstanter Ausdruck zugewiesen wurde.
-
314159265358979 schrieb:
Gugelmoser schrieb:
Doch, das ist genau richitg so. Die Größe eines Arrays muss ein konstanter Ausdruck sein und das ist
n, da es const-spezifiziert ist und mit einem konstanten Ausdruck initialisiert wurde.const hat mit konstanten Ausdrücken erstmal nichts zu tun. Nicht alles, was const ist, ist auch ein konstanter Ausdruck.
Habe ich auch nicht behauptet.
-
Gugelmoser schrieb:
, da es const-spezifiziert ist
Nein, hast du natürlich nicht. Es heißt übrigens qualifiziert.
-
Tja, ohne Bibliotheksfunktion läuft es wohl auf WriteConsole auf Windows bzw auf write bei dem Rest der Welt heraus.

-
Hallo Leute,
mein Dozent sagte, es gänge mit Referenzparametern. Trotzdem bin ich mir noch nicht ganz im Klaren. Ich werde es aber einmal probieren.
Grüße
Kakashi
-
das haben wir dir doch auch gesagt.
die frage war, wie die ausgabe ohne cout und bibliotheksfunktionen erfolgen sollte.
-
unskilled schrieb:
die frage war, wie die ausgabe ohne cout und bibliotheksfunktionen erfolgen sollte.
Das ist keine Frage. Ohne Bibliotheksfunktionen könntest du dir allerhöchstens selber ein
ostream-Objekt basteln und das an den Ausgabestream koppeln (der wiederum auch eine Bibliotheksfunktion ist); das ist allerdings völlig unmöglich für einen Anfänger zu schaffen.
-
dummerweise mal wieder komplett fail deine antowrt: man braucht kein ostream-objekt zu basteln, da man die stream-eigenschaften nicht zwangsläufig braucht. aber ansonsten hast du den widerspruch super bemerkt...
-
Mit der Einschränkung wird nur gemeint sein, dass der Kram nicht innerhalb der Funktion sieb ausgegeben werden soll, sondern in main. Der Zweck der Übung scheint ja zu sein, call-by-reference zu lernen.