Verständnisproblem

Thaelisin

Mitglied
Hallo Leute ich habe folgenden Code, aus einer meiner Übungsklausuren.
Aber ich verstehe nicht wie man auf das Ergebnis kommen soll. Vielleicht könnt ihr mir wieder erklären wie das funktioniert.

Code:
#include <iostream>
using namespace std;
int z = 1;
void fkt(int &x)
{
int y = x + z + 1;
for (int z = 1; z < 4; z += 2)
{
x = x * y + z;
}
}
void main (void)
{
int z = 1;
fkt(z);
cout << z << endl;
}
 

vfl_freak

Premium-User
Moin,
ich verstehe nicht wie man auf das Ergebnis kommen soll
Du kannst es händisch mit Papier und Stift machen, in dem Du die jeweiligen Variablenwerte in jeden Durchlauf setzt und ausrechnest !
Oder dur tippst es ein und probierst es einfach aus (evtl. per Debugger, dann kannst Du die werte in den einzelnen Steps nachvollziehen - oder ggf. per SysOut)!

BTW: was sollte denn DMn denn rauskommen?
Ich vermute mal 15 .... ;)

VG Klaus
 

cwriter

Erfahrenes Mitglied
Aber ich verstehe nicht wie man auf das Ergebnis kommen soll. Vielleicht könnt ihr mir wieder erklären wie das funktioniert.
Also ist die Frage nach der Ausgabe?

Es bietet sich bei solchen Aufgaben an, Computer zu spielen, also zuerst mal die main() anzuschauen.
Dann sieht man als erstes Statement "int z = 1;" und man merkt sich, dass 'z' den Wert 1 hat.
Dann sieht man fkt(z). Man schaut nach, was die Definition von fkt(int) ist (falls es eine Definition von fkt(bool) gäbe, wäre diese zu ignorieren (siehe "function overloads")).
Die Definition hat den einen Parameter int& x. Nota bene: Das ist eine Referenz.
Nun gibt es 2 Möglichkeiten: Entweder du ersetzt im Geiste alle 'x' in der Funktion durch 'z' (kann relativ schnell vergessen werden und - in diesem speziellen Fall - würdest du die beiden z (einmal global, einmal lokal in main() verwechseln), oder du denkst daran, am Ende der Funktion den Wert des Parameters 'z' auf den Wert von 'x' zu setzen.

Nun ist die erste Zeile von fkt() schon recht gemein:
int y = x + z + 1;

Hier müssen wir die Symbole nachschlagen:
1) Was ist x?
-> Antwort: x ist der Parameter.
-> Was ist der Wert des Parameters?
-> Er ist 1.
Also verbleibt
int y = 1 + z + 1;
2) Was ist z?
-> Antwort: z ist eine globale Variable mit dem Wert 1.
Es verbleibt:
"int y = 1 + 1 + 1;", also ist y == 3.

Dann kommt ein loop mit einer weiteren lokalen Variable z.
Je nach Präferenz gibt es bei Loops 2 Möglichkeiten:
1) Loop Unrolling: Wir ersetzen den Loop durch äquivalente Statements:
Also in deinem Beispiel:
C:
for (int z = 1; z < 4; z += 2)
{
    x = x * y + z;
}

//Loop unrolling: Setup und erster Durchgang:
//Das Scope {} ist nur zur Sicherheit, falls es eine Lokale Variable im Loop gäbe, die gleich wie eine lokale Variable der Funktion heisst.
{
    int z = 1; //Setup (erstes Loop-Statement)
    //Unrolling 1:
    if(z < 4) {
        x = x * y + z;
       z += 2; //z ist jetzt 3
    }
   
    //Hier die nächsten Schritte des Loops. Achtung: Das Setup (int z = 1) hier weglassen!
    for(;z < 4; z += 2)
    {
        x = x * y + z;
    }
}

//Und noch ein Schritt:
{
    int z = 1; //Setup (erstes Loop-Statement)
    //Unrolling 1:
    if(z < 4) { //erfüllt, z == 1
        x = x * y + z; //x = 1 * 3 + 1; //x war parameter, daher wieder auflösen, y ist lokal (oben eruiert), z ist hier das lokale z des Loops.
        z += 2; //z ist jetzt 3
    }
 
    //Hier die nächsten Schritte des Loops. Achtung: Das Setup (int z = 1) hier weglassen!
    if(z < 4) { //erfüllt, z == 3
        x = x * y + z; //x = 4 * 3 + 3; //x im oberen Schritt schon verändert
        z += 2; //Shortcut: Da z == 5 wird der Loop abgebrochen werden, korrekterweise fehlt noch ein Schritt.
    }

    if(z < 4) { //nicht erfüllt, z == 5
        //Don't care
    }
     
}
Der 2. Weg ist schneller: Schreibe dir im Loopdurchgang einfach die Variablenwerte auf.
C:
for (int z = 1; z < 4; z += 2)
{
//Durchgang mit z == 1, x == 1, y == 3:
//x == 1 * 3 + 1 == 4
//Durchgang mit z == 3, x == 4, y == 3:
//x == 4 * 3 + 3
//Durchgang mit z == 5: Kommt nicht vor, Abbruch.
x = x * y + z;

}

Damit ist fkt auch schon fertig, und x ist lokal nun 15. Da es sich um eine Referenz handelt, ist auch das lokale z der main() 15.
Die Ausgabe ist somit
Ich vermute mal 15 .... ;)

Hilft das so weiter?

Gruss
cwriter
 
Zuletzt bearbeitet:

cwriter

Erfahrenes Mitglied
Ja 15 ist schon richtig, aber wie soll das gehen. Aber fehlt mir da nicht eine Variable :(
Welche denn? :)
Als Faustregel: Ein paar Worte mehr zu Beginn ersparen Nachfragen und damit Zeit und Nerven. Der Titel des Themas ist auch nicht gerade sehr aussagekräftig.
Alles in Ordnung, einfach in Zukunft vielleicht dran denken.

Gruss
cwriter