Funktionen (Rückgabewert/Parameterwert)
-
Ui ui,
warum willst du gleich mit Ein- und Ausgabe arbeiten, wenn du Funktionen lernen willst? Versuch es doch einmal zunächst im mathematischen Sinne.Sagen wir du gibst die Variable x vor und möchtest in y das Quadrat von x speichern: Wie musst du in Zeile 5 des folgenden Codes die Funktion definieren, dass du f(x) = x^2 programmiert hast?
#include <iostream> using namespace std; // hier die Funktion f definieren int main() { double x = 1.0; double y = f(x); return 0; }
Gruß,
-- Klaus.
-
Ich denke ich brauche nur mal diesen durchbruch um das richtig zu verstehen. Das fällt mir aber sehr schwer..
#include <iostream> using namespace std; double f(x); { Quadrat = x*x; return Quadrat; } int main() { double x = 1.0; double y = f(x); cout<< y; return 0; }
-
ZetaGamma schrieb:
Ich denke ich brauche nur mal diesen durchbruch um das richtig zu verstehen. Das fällt mir aber sehr schwer..
Um Funktionen zu verstehen, mußt Du zwischen dem Formalparameter und dem Aktualparameter unterscheiden.
Der Formalparameter erscheint im Kopf der Funktionsdefinition und kann im Funktionsrumpf wie eine lokale Variable benutzt werden, nur daß er nicht initialisiert werden muß. Er sollte ja nicht einmal initialisiert werden, weil das passiert nämlich beim Aufruf der Funktion durch den Aktualparameter.
Der Aktualparameter erscheint beim Aufruf der Funktion und kann eine Konstante (int oder Stringliteral etc.) oder auch eine Variable des Aufrufers sein. Die Variable des Aufrufers kann zwar den gleichen Namen wie der Formalparameter haben, muß aber nicht.
Der Aufrufer muß beim Funktionsaufruf alle formalen Parameter mit Werten versorgen. In C++ kann man aber von rechts einen, mehrere oder gar alle formalen Parameter mit Defaultwerten versehen. Ist sowas gegeben, kann der Aufrufer diese Parameter beim Funktionsaufruf weglassen stattdessen werden die Defaultwerte übergeben. Das muß aber dem Aufrufer bekannt sein, weshalb das in einer Funktionsdeklaration gemacht werden muß.
mfg Martin
-
Bashar schrieb:
Wenn du es wirklich lernen willst, musst du dir andere Quellen als solche Videos suchen. Nicht nur, dass Videos generell ein schlechtes Medium für solchen Stoff darstellen, der Typ, der das macht, ist auch offensichtlich nicht gerade ein Experte...
Über die Qualität des Autors als C++-Entwickler lässt sich nur sehr schwer was sagen. Seine didaktischen Fähigkeiten tendieren aber gegen 0. Lustig fand ich den Teil, wo er die beiden Operanden einer Summe vertauscht. Er hat ein wenig am Film geschnippselt, weshalb das irgendwie aus dem Zusammenhang fiel. Aber so weit ich weiß, lernt man das Kommutativgesetz der Addition schon in der Grundschule spätestens aber in der 5. Klasse.
mfg Martin
-
So die zwei Situationen ohne Rückgabewert/Ohne Übergabeparameter und Mit Rückgabewert/Ohne Übergabeparameter verstehe ich nun. Auch was der Formalparameter macht ist mir nun klar. Er ist eine Art deklarierter Wert, bloß als eigenes Programm.
Können Sie mir eventuell nur erklären, wie der Computer hier denkt bei den markierten Stellen:
#include <iostream> using namespace std; //Prototypen von allen Funtkionen im Programm void multiplikation(float zahl_1, float zahl_2);/*ohne Rückgabewert, mit Übergabeparameter*/ int main(void) { [b]float zahl_1, zahl_2;[/b] cout << "Zahl 1 eingeben: "; cin >> zahl_1; cout << "Zahl 2 eingeben: "; cin >> zahl_2; multiplikation(zahl_1, zahl_2);//ohne Rückgabewert, mit Übergabeparameter cin.sync(); cin.get(); return 0; } void multiplikation [b](float a, float b)[/b] { cout << a * b; }
Ich sehe vier verschiedene Variablen. Dabei sind zahl_2 und zahl_2 deklarierte Variablen. Initialisiert werden diese durch die Eingabe vom Benutzer aus. Wieso das float a und float b ? Das versteh ich nicht. Wieso a*b ? Wieso nicht zahl_1 * zahl_2 ?
-
Hallo ZetaGamma,
ZetaGamma schrieb:
#include <iostream> using namespace std; double f(x); { Quadrat = x*x; return Quadrat; }
Da sind schon ein paar richtige Ideen dabei:
Zeile 5: Richtig, dass du den Rückgabewert der Funktion definierst, nämlich double. Auch richtig, dass der Funktionsname f lautet. Unvollständig: Die Funktion weiß noch nicht welchen Typ sie als x übergeben bekommt, als muss aus
double f(x)
eindouble f(double x)
werden.
Falsch ist noch in Zeile 5, dass du mit Semikolon abschließt, es muss der Rumpf - das in geschweiften Klammern folgen, alsodouble f(double x) { // Inhalt ... }
Falsch ist noch in Zeile 7, dass die Variable Quadrat innerhalb der Funktion (also innerhalb der geschweiften Klammern von Zeile 7 bis 11) nicht definiert ist, also eher
double f(double x) { double Quadrat = x * x; return Quadrat; }
Klar soweit?
Gruß,
-- Klaus.
-
Da fehlen wohl noch mehr Begriffe. Deklaration, Definition, Initialisierung.
Eine Deklaration teilt dem Compiler mit, daß es was gibt. Das Objekt wird aber nicht im Speicher angelegt. Bei Variablen macht man dies nur für globale Variablen. Beispiele sind
extern int myGlobalStuff; int myFunction( int, int ); class myClass;
Eine Definition teilt dem Compiler mit, daß er Daten oder Code im Speicher anlegen muß. Beispiele:
int myVariable; int myFunc( int param ) { return param; } class myClass { int member; }
EDIT: Bei Typdefinitionen wird natürlich nichts im Speicher erzeugt.
Eine Initialisierung gibt es nur für Variablen. Da wird der initiale Wert reingeschrieben
myVariable = 0;
Die Initialiserung und Deklaration kann (muß aber nicht) in einem Schrit erfolgen:
int myVar=0;
Eine Externdeklaration einer Variablen mit Initialiserung ist auch gleich eine Definition:
extern int myVar = 0;
Eine Definition ist auch immer eine Deklaration. Umgekehrt gilt dies nicht.
Deklarieren darfst Du jedes Objekt beliebig oft, definieren aber nur einmal. Mehrere Deklaration dürfen sich aber nicht widersprechen. Daher deklariert man jedes Objekt nur einmal in der Headerdatei (falls man es in anderen Modulen braucht) oder am Anfang der Quelldatei.
Variablen darfst Du beliebig oft initialiseren, allerdings überschreibt jede Initialiserung die Werte der vorhergehenden Initialiserungen.
Bei der Definition einer globalen oder statischen Variablen wird der Speicher für die Variable im Datensegment des Programmes reserviert. Bei der Definition einer Funktion wird dies im Codesegment gemacht.
Bei der Definition einer lokalen Variable wird dies für gewöhnlich auf dem Stack der CPU passieren. Es kann aber auch ein Register benutzt werden. Das gleiche gilt aber auch für Funktionsparameter. Bei Variablen ist die Funktions selbst dafür verantwortlich, sich den Platz auf dem Stack zu reservieren. Bei Funktionsparametern ist des der Aufrufer nicht die aufgerufene Funktion, die den Stack entsprechend manipuliert. Muß ja auch sein, da der Aufrufer ja schließlich die Aktualparameter in die Formalparameter schreiben muß. Das Aufräumen des Stacks geschieht dann immer hinterher. Bei den Parameter nachdem die aufgerufene Funktion beendet wurde *). Bei lokalen Varablen bevor die Funktion zurück springt.
Zu Deinem Code:
Zeile 12 reserviert zwei float variablen auf dem Stack.
In Zeile 18 wird der Inhalt der beiden Variablen auf den Stack geschrieben und somit der Speicher für die beiden Formalparameter in Zeile 25 reserviert. Zeile 27 liest dann genau diesen Speicher nicht aber den aus Zeile 12.mfg Martin
Es gibt zwar noch andere Aufrufkonventionen aber wir wollen heute nicht übertreiben.
-
mgaeckler schrieb:
EDIT: Bei Typdefinitionen wird natürlich nichts im Speicher erzeugt.
Da fällt mir noch ein, der Unterschied zwischen einer Typdefinition und einer -deklaration ist.
Nach einer Typdeklaration darfst Du den Typ benutzen, wann immer ein Typ gefragt wird aber solange der Compiler nicht die Größe kennen muß. Wenn der Compiler die Größe kennen muß, um z.B. eine Variable zu definieren, muß auch der Typ definiert sein.mfg Martin
-
mgaeckler schrieb:
Bashar schrieb:
Wenn du es wirklich lernen willst, musst du dir andere Quellen als solche Videos suchen. Nicht nur, dass Videos generell ein schlechtes Medium für solchen Stoff darstellen, der Typ, der das macht, ist auch offensichtlich nicht gerade ein Experte...
Über die Qualität des Autors als C++-Entwickler lässt sich nur sehr schwer was sagen.
Doch, guck dir Folge #17 an.
-
Bashar schrieb:
mgaeckler schrieb:
Bashar schrieb:
Wenn du es wirklich lernen willst, musst du dir andere Quellen als solche Videos suchen. Nicht nur, dass Videos generell ein schlechtes Medium für solchen Stoff darstellen, der Typ, der das macht, ist auch offensichtlich nicht gerade ein Experte...
Über die Qualität des Autors als C++-Entwickler lässt sich nur sehr schwer was sagen.
Doch, guck dir Folge #17 an.
Also wirklich!
Hat doch glatt vergesen den Speicher am Ende des Programmes zu löschen:for (iter = list.begin(); iter != list.end(); ++iter) { delete &*iter; }
Böses Speicherleck.
-
Not sure if joking...
Ich hoffe mgaeckler macht sich ein eigenes Bild. Und der OP lässt sich nicht verwirren.
-
Bashar schrieb:
Not sure if joking...
Ja, joking.
Hätt ich net machen sollen.
-
Nathan schrieb:
Bashar schrieb:
Not sure if joking...
Ja, joking.
Hätt ich net machen sollen.Richtig. Das Problem ist, daß ja die meisten Programmiertechniken, die Anfänger lernen sollen, erfunden wurden, um komplexe Programme sicher entwickeln zu können. Viele der Programmiertechniken, die bei Profis so verpönt sind (globale Variablen, vergessen der Speicherfreigabe etc.), können bei simplen Helloworldprogrammen problemlos benutzt werden. Vergessener Speicher wird vom OS recycled. Probleme mit globalen Variablen treten bei simplen Programmen eher nicht auf bzw. können leicht beherscht werden.
Programmierer wollen aber über das Anfängerstadium hinaus. Dann müssen solche Techniken ins Fleisch und Blut übergangen sein. Daher sollten auch solche Tutorials, die für Anfänger gedacht sind, solche Techniken verwenden.
Eine Integervariable mit new zu erzeugen und dieses nie freizugeben ist daher dumm. Sowas hat in einem Tutorial nichts verloren. Überhaupt stellt sich die Frage, warum er eine Variable mit new erzeugt. Eine lokale Variable hätte es auch getan.
Sicher, auch ich mache mir nicht immer die Mühe, wenn ich hier Beispielcode poste, alle Facetten aus zu formulieren. Das ist aber dann OK, wenn es für die Beantwortung der aktuellen Frage nicht notwendig ist, und ich schreibe es auch (fast) immer dazu.
mfg Martin
-
mgaeckler schrieb:
Überhaupt stellt sich die Frage, warum er eine Variable mit new erzeugt.
Weil er so einiges nicht kapiert hat.
Für alle, die das Video auch nicht angesehen haben, er macht etwa sowas:
std::list<int> liste; std::list<int>::iterator it; for (int i = 0; i < 10; i++) { int *p = new int(10 + i); liste.push_back(*p); } for (it = liste.begin(); it != liste.end; it++) { cout << *it << endl; // Hier stand zuerst nur cout << it << endl, dann kommt eine Bemerkung wie // "Ach wir haben ja Pointer in der Liste", und er fügt das Sternchen hinzu }
Sorry, aber da kann man ja mehr von Jürgen Wolf lernen.
-
Bashar schrieb:
mgaeckler schrieb:
Überhaupt stellt sich die Frage, warum er eine Variable mit new erzeugt.
Weil er so einiges nicht kapiert hat.
Für alle, die das Video auch nicht angesehen haben, er macht etwa sowas:
std::list<int> liste; std::list<int>::iterator it; for (int i = 0; i < 10; i++) { int *p = new int(10 + i); liste.push_back(*p); } for (it = liste.begin(); it != liste.end; it++) { cout << *it << endl; // Hier stand zuerst nur cout << it << endl, dann kommt eine Bemerkung wie // "Ach wir haben ja Pointer in der Liste", und er fügt das Sternchen hinzu }
Sorry, aber da kann man ja mehr von Jürgen Wolf lernen.
Das Video habe ich gar nicht gesehen. Der wiederholt seinen Scheiß auch noch.
mfg Martin
-
ja, ist auch lustig wie er da std::vector und std::list verwechselt und wie er den speicher in einem dynamischen container manuell allozieren will. das problem ist ja nichtmal dass es solche tutorials und leute die solche tutorials machen gibt sondern dass dann auch noch leute die c++ lernen wollen online tutorials als lerngrundlage ernst nehmen und betrogen werden. ich kann allen nur empfehlen: buch kaufen und lesen. ist das gescheiteste.
-
Es geht nichts über ein gutes Buch. Wenn du programmieren lernen willst, leg dir ein entsprechendes Buch zu oder leih dir eines aus und arbeite es durch. Vergiss Tutorials, ganz besonders Videotutorials. Sie haben ihren Platz, aber dieser Platz ist definitiv nicht hier.