Problem mit zeigern!
-
int func3(int& number, int& number2) { number=130; number2=240; return number, number2; }Wenn die Variablen so übergeben werden, dann brauchst du sie nicht mehr zurückgeben. Denn dann weisen die Änderungen innerhalb der Funktion gleich die neuen Wert auf die übergebenen Variablen zu. Sprich, number = 130 bezieht sich dann auf die Variable welche du beim Funktionsaufruf übergibst und muss daher nicht per return zurückgegeben werden.
Außerdem klappt das immer noch nicht, zwei Werte per Return zurück zu geben. Strukturier das so um, dass maximal ein Rückgabewert vorhanden ist, sonst klappt das nicht ohne weiteres.
-
da der komma operator von links nach rechts ausgewertet wird duerfte bei diesem konstrukt wohl nur number2 zurueckgegen werden. -nur mal so da der compiler offensichtlich keine warnung ausgibt...
-
Erstmal Guten Morgen

Nun bei mir gibt er beide werte ohne probleme wieder zurück hab es eben erst getestet.
Nur bei dem case 4: und der dazugehörigen funktion func4 gibt es noch probleme!
Aber ich weiss nicht was ich tun soll
-
MartinMilbret schrieb:
Erstmal Guten Morgen

Nun bei mir gibt er beide werte ohne probleme wieder zurück hab es eben erst getestet.Das ist nicht dein ernst, oder?
Ich meine warum glaubst du nicht was man dir sagt?
Was hast du denn überhaupt getestet würde mich mal interessieren, denn mit deiner main testest du garnichts.func1(zahl, zahl2);Du machst nichts mit dem rückgabewert, also kannst du auch nicht wissen was zurückgegeben wurde.
Wie schon gesagt wurde es wird NUR EIN WERT zurückgegeben.
Du hast den beiden Zeigern in der Funktion schon die Werte für ihre Variablen gegeben. Dass du sie zurückgibst ist somit unnötig, dazu ist es noch falsch.
-
Ich denke wir sind hier:
int func3(int& number, int& number2) { number=130; number2=240; return number, number2; }Das mit fun1 hatten wir gestern schon geklärt

-
Wie schon mehrfach gesagt, das ist Quatsch. Du kannst nicht mehrere Werte zurückgeben. Geht nicht. Im Ernst. Du kannst einen Zeiger auf ein Array zurückgeben, oder du kappselst deine Werte in einer Struktur.
-
Du kannst (egal in welcher Deiner Funktionen) so nicht zwei Werte mit return zurückgeben. Dennoch ist der Ausdruck
return number1, number2;legal. Zurückgegeben wird aber nur number2. Siehe Komma-Operator.
Funktionen dieser Art können nur einen Wert zurückgeben. Dabei ist es egal wieviele Parameter sie bekommt und ob das Zeiger oder Referenzen sind. Als Rückgabewert bezeichnet man im Allgemeinen den von return zurückgegebenen Wert
int func() // diese Funktion gibt genau einen int zurück { return 120; } // Aufruf int a = func(); cout << a << "\n";Wenn Du tatsächlich zwei Werte zurückgeben möchtest, kannst zu z.B. std::pair<int, int> verwenden oder Dir einen Struct basteln. Das muss aber zum Rückgabewert der Funktion passen:
std::pair<int,int> func() { return std::pair<int, int>( 3, 4); }Deine func3 ändert Werte per Referenz, d.h. Du übergibst Ihr Variablen und die Funktion schreibt (möglicherweise) das Ergebnis in diese Variablen.
void func3(int& number, int& number2) // diese Funktion gibt gar nichts zurück, darf aber die ihr übergebenen Variablen ändern { number=130; number2=240; } // Aufruf int a = 1; int b = 2; cout << a << ", " << b << "\n"; func3( a, b); cout << a << ", " << b << "\n";Für Deine func4 kannst Du folgendes machen:
void func4( int** number1, int** number2) { *number1 = new int; **number1 = 130; *number2 = new int; **number2 = 240; } // Aufruf int *a = 0; int *b = 0; // *a darfst Du noch nicht schreiben, da a noch auf keinen gültigen Speicher zeigt func4( a, b); cout << *a << ", " << *b << endl; delete a; // Speicher wieder freigeben delete b; // Speicher wieder freigebenSowas wie func4 versucht man aber zu vermeiden, da der Aufrufer den Speicher wiederfreigeben muss. Das wird aber oft vergessen und schon hat man ein Speicherleck.
Wenn Du eine Funktion hast:
int a = berechneWas(1, 2);weisst Du, dass a danach einen Wert hat. Du kannst Dich darauf verlassen, ohne den Code der Funktion zu lesen (Exceptions sind eine Ausnahme, dann wird aber auch Dein Code nicht weiter ausgeführt).
Bei
int a = 0; int b = 0; berechneWas( a, b);weisst Du nicht, ob a und b durch den Aufruf verändert werden. Selbst wenn die Werte per Referenz übergeben werden (also wie in func3), muss die Funktion sie nicht ändern. Es ist völlig legal, einfach nichts zu tun. Du kannst Dich also nicht darauf verlassen, dass a und b verändert werden.
Deswegen versucht man Änderungen über Referenzen nur dann zu machen, wenn es nicht anders geht (z.B. um mehr als einen Wert zu ändern). Und wenn man Referenzen nicht ändern will, dann sollte man das Schlüsselwort const zu benutzen (bzw. bei PODs (also int, short und co) lässt man die Referenz weg), um dem Aufrufer zu sagen: Da wird nichts verändert
-
Okay also func4 werde ich mal umschreiben. und auch func3 und nochmals danke für die hilfe

Okay hier mal der fast funktionierende code:
#include<iostream> using namespace std; /*Zeiger test*/ void func1(int, int); int* func2(int*, int*); int func3(int&, int&); void func4(int*, int*); int main() { int zahl; int zahl2; int* pzahl; int* pzahl2; pzahl=&zahl; pzahl2=&zahl2; cout<<"Geben sie 2 zahlen ein"<<endl; cin>>zahl; cin>>zahl2; cout<<"Geben sie nun die zeiger art ein die sie haben wohlen"<<endl <<"Hier die Uebersicht(1=Werteuebergabe, 2=Zeigerwerteuebergabe, "<<endl <<"3=Uebergabe per Reference, 4=heapspeicher nutzung"<<endl; int choice; cin>>choice; switch(choice) { case 1: func1(zahl, zahl2); cout<<zahl<<endl <<zahl2<<endl; break; case 2: func2(&zahl, &zahl2); cout<<zahl<<endl <<zahl2<<endl; break; case 3: func3(zahl, zahl2); cout<<zahl<<endl <<zahl2<<endl; break; case 4: int *zahl; int *zahl2; func4(zahl, zahl2); cout<<*zahl<<endl <<*zahl2<<endl; delete *zahl; delete *zahl2; cout<<zahl<<endl <<zahl2<<endl; break; default: cout<<"Eingabe Ungueltig"<<endl; break; } system("PAUSE"); } void func1(int number, int number2) { number=100; number2=200; cout<<number<<endl <<number2<<endl; } int* func2(int* pnumber, int* pnumber2) { *pnumber=110; *pnumber2=220; return pnumber, pnumber2; } int func3(int& number, int& number2) { number=130; number2=240; return number, number2; } void func4(int** number, int** number2) { *number=new int; *number2=new int; **number=140; **number=260; cout<<**number<<endl <<**number2<<endl; }
-
Sorry, aber dein
return number, number2ist immernoch Nonsense. Wie schon viele meiner Vorredner gesagt haben, kannst du nur einen einzigen Wert zurückgeben.
Lass dir mal erklären, was deine Funktionen genau machen:- func1:
Beim Aufruf dieser Funktion wird auf dem Stack Platz für zwei int-Variablen reserviert, nämlich number und number2. Diese beiden Speicherplätze werden mit den Werten belegt, die du der Funktion übergibst. Danach werden diese beiden Speicherplätze sofort geändert, das hat aber keine Wirkung auf die Variablen, die du beim Funktionsaufruf übergeben hast. Diese beiden Variablen wurden nämlich in die neuen Speicherpläze kopiert; eine Veränderung der Kopien verändert nicht die Originale. Du könntest also func1 genausogut ohne Parameter definieren.
- func2:
Du übergibst der Funktion zwei Zeiger, also Verweise auf Speicherbereiche, wo jeweils ein int drin ist. Danach veränderst du dei Speicherbereiche (was auch Auswirkungen außerhalb der Funktion hat).
Die dann folgende return-Anweisung erwartet ein einziges Argument. Dieses Argument ist in deinem Falle (pnumber, pnumber2). Es enthält den Komma-Operator, der von links nach rechts ausgewertet wird, bevor das Ergebnis der return-Anweisung übergeben wird. Der Rückgabewer des Kommaoperators ist das ergebnis der Auswertung des rechten Arguments. Die Auswertung läuft also wie folgt:
- Werte pnumber aus -> Auswirkungen: keine. Ergebnis: Wert von pnumber
- Werte pnumber2 aus -> Auswirkungen: keine. Ergebnis: Wert von pnumber2
- gebe das Ergebnis des zweiten Arguments zurück: Wert von pnumber2
Fazit: die returnanweisung gibt nur den Wert von pnumber2 zurück, das pnumber davor hat keinerlei Auswirkungen und wird vermutlich vom Compiler wegoptimiert.- func3:
Das gleiche Spiel wie func2, nur dass diesmal Referenzen statt Zeigern benutzt werden. Der Unterschied ist, dass man bei Referenzen nicht immer dereferenzieren muss (also kein * voranstellen), und dass Referenzen einmal an eine Variable gebunden werden und danach nicht mehr verändert werden können. Man könnte auch sagen, sie sind eine Art idiotensichere Zeiger. (Ich weiß, sie sind noch mehr und teils auch weniger als das...)
Die Auswirkungen sind wie bei func2: Da du nur mit Referenzen auf Zahlen arbeitest, die an die Funktion übergeben werden, wird kein extra Speicher reserviert und die Zahlen ändern sich auch (anders als im ersten beispiel, wo du nur die Kopien veränderst). Bei der return-Anweisung wieder der gleiche Mist wie bei func2: du gibst im Endeffekt nur den Wert von number2 zurück.- func 4
Du übergibst der Funktion einen zeiger auf einen zeiger auf Ints. Sofort danach belegst du den Zeiger, auf den der Zeiger zeigt (toll, ne?) per "new" mit einem neuen Wert. Was aber, wenn der zeiger vorher auf einen anderen, dynamisch allokierten Bereich im speicher gezeigt hat? Dann verwaist dieser Bereich, weil niemand mehr auf ihn zeigt. Tolles Speicherleck... (ein delete *number hilft übrigens nicht, könnte ja sein, dass der Zeiger nicht auf dynamischen speicher sondern auf den heap zeigt, dann kriegst du einen Laufzeitfehler)
Als nächstes veränderst du den neu geschaffenen Speicher, gibst die Werte aus und kehrst zum Aufrufer zurück. der weiß normalerweise aber nicht, dass du neuen Speicher geholt hast, und deshalb wird er den Speicher auch nicht wieder freigeben. Speicherleck Nummer 2...Du solltest dir echt nochmal ein wenig Literatur zum Thema Arbeit mit Zeigern und vor allem zum Thema Funktionen, Parameterübergabe und Rückgabewerte durchlesen. Es gibt hunderte von guten und weniger guten, ausführlicheren und knapperen, leicht verständlichen und weniger einfachen einführenden Büchern zu den Themen...
-
Sorry gab nur vergesen es zulöschen

-
Hier mal ein code update mit func4:
#include<iostream> using namespace std; /*Zeiger test*/ void func1(int, int); int* func2(int*, int*); void func3(int&, int&); int* func4(); int main() { int zahl; int zahl2; int* pzahl; int* pzahl2; pzahl=&zahl; pzahl2=&zahl2; cout<<"Geben sie 2 zahlen ein"<<endl; cin>>zahl; cin>>zahl2; cout<<"Geben sie nun die zeiger art ein die sie haben wohlen"<<endl <<"Hier die Uebersicht(1=Werteuebergabe, 2=Zeigerwerteuebergabe, "<<endl <<"3=Uebergabe per Reference, 4=heapspeicher nutzung"<<endl; int choice; cin>>choice; switch(choice) { case 1: func1(zahl, zahl2); cout<<zahl<<endl <<zahl2<<endl; break; case 2: func2(pzahl, pzahl2); cout<<zahl<<endl <<zahl2<<endl; break; case 3: func3(zahl, zahl2); cout<<zahl<<endl <<zahl2<<endl; break; case 4: int* pzahl2; pzahl2=func4(); delete pzahl2; cout<<zahl<<endl <<zahl2<<endl; break; default: cout<<"Eingabe Ungueltig"<<endl; break; } system("PAUSE"); } void func1(int number, int number2) { number=100; number2=200; cout<<number<<endl <<number2<<endl; } int* func2(int* pnumber, int* pnumber2) { *pnumber=110; *pnumber2=220; return pnumber, pnumber2; } void func3(int& number, int& number2) { number=130; number2=240; cout<<number<<endl <<number2<<endl; } int* func4() { int* pnumber=new int; *pnumber=10; cout<<*pnumber<<endl; return pnumber; }Wenn noch fehler drin sind bitte melden

-
Deine func2() soll immer noch 2 Werte zurückgeben, das geht nicht und wird auch in Zukunft mit C++ nicht gehen. Eine Funktion gibt immer nur maximal!!!! 1 Element ihres Rückgabetyps zurück. Natürlich ist es sinnlos einen Rückgabetyp (ungleich void) zu vereinbaren und dann nicht zu nutzen. Auch wenn der Compiler solche Konstrukte mit dem Komma-Operator vielleicht zulässt wird die Funktion so wie sie dort steht nicht das zurückgeben was du von ihr eigentlich zurückgeben lassen willst.
-
Danke für die info
hab ich wieder mal gepennt
bin ja noch am anfang und lehrne ja noch welche sachen man meiden muss 
-
Mal ne dumme Frage: Was macht der Komma Operator?
Ich weiß das man nur ein Wert zurückgeben kann, aber mir ist bis jetzt schleihaft warum sich so ein Qwatsch kompelieren lässt.
-
Wie pumuckl schon sagte:
pumuckl schrieb:
Es enthält den Komma-Operator, der von links nach rechts ausgewertet wird, bevor das Ergebnis der return-Anweisung übergeben wird.
...
Fazit: die returnanweisung gibt nur den Wert von pnumber2 zurück, das pnumber davor hat keinerlei Auswirkungen und wird vermutlich vom Compiler wegoptimiert.
-
lol
-
Okay versuch nummer 103
:#include<iostream> using namespace std; /*Zeiger test*/ void func1(int, int); void func2(int*, int*); void func3(int&, int&); int* func4(); int main() { int zahl; int zahl2; int* pzahl; int* pzahl2; pzahl=&zahl; pzahl2=&zahl2; cout<<"Geben sie 2 zahlen ein"<<endl; cin>>zahl; cin>>zahl2; cout<<"Geben sie nun die zeiger art ein die sie haben wohlen"<<endl <<"Hier die Uebersicht(1=Werteuebergabe, 2=Zeigerwerteuebergabe, "<<endl <<"3=Uebergabe per Reference, 4=heapspeicher nutzung"<<endl; int choice; cin>>choice; switch(choice) { case 1: func1(zahl, zahl2); cout<<zahl<<endl <<zahl2<<endl; break; case 2: func2(pzahl, pzahl2); cout<<zahl<<endl <<zahl2<<endl; break; case 3: func3(zahl, zahl2); cout<<zahl<<endl <<zahl2<<endl; break; case 4: int* pzahl2;//deklaration des zeigers auf int zahl2 pzahl2=func4();//zeiger an func 4 übergeben delete pzahl2;//speicher löschen cout<<zahl<<endl <<zahl2<<endl; break; default: cout<<"Eingabe Ungueltig"<<endl; break; } system("PAUSE"); } void func1(int number, int number2) { number=100; number2=200; cout<<number<<endl <<number2<<endl; } void func2(int* pnumber, int* pnumber2) { *pnumber=110; *pnumber2=220; } void func3(int& number, int& number2) { number=130; number2=240; cout<<number<<endl <<number2<<endl; } int* func4() { int* pnumber=new int;//speicherplatz holen *pnumber=10;//speicher wert zuweisen cout<<*pnumber<<endl;//wert ausgeben return pnumber;//zeiger zurückgeben }
-
Er hats endlich kapiert

Nix für ungut, aber zusehen, dass endlich kein return nummer1, mummer2 in deinem Code steht ist echt schön.
-
Jo trotz meines Realschulabschlusses(@WIP) stand ich ne weile auf der leitung

Ferien halt
-
MartinMilbret schrieb:
trotz meines Realschulabschlusses(@WIP) stand ich ne weile auf der leitung

lol?