Seite 1 von 2

2 Variablen zurückgeben aus Rekursiver Funktion

Verfasst: Di Jan 10, 2012 4:30 pm
von DANrulz81
Hallo zusammen,

ich hab ein bisschen im Algorythmusforum gestöbert und bin dabei auf das Collatz - Problem gestoßen. Ich hab den Code von einem C++ - Schnipsel umgebaut auf C:

Code: Alles auswählen

#include <stdio.h>

int collatz(int start, int zaehler)
{
        if ( (start == 1) || (start == -1) ) {
                return 1;
        }
        printf("\n%i",start);
        if (start%2)
        {
                return collatz(3*start + 1, zaehler++);
        }
        else
        {
                return collatz(start / 2, zaehler++);
        }
}

int main(void)
{
    int start=0,zaehler=0;

    printf("\nBitte geben sie eine Startzahl ein: ");
    scanf("%i",&start);

    collatz(start,zaehler);
    printf("\n1");
    printf("\n\nAnzahl der Durchg\x84nge: %i",zaehler);

    return 0;
}
Dabei wollt ich noch einen Zähler einbauen, der mir sagt, wieviel Durchgänge stattgefunden haben. So wie ich das eingebaut habe, bekomm ich immer eine "0". Woran liegt das?

Re: 2 Variablen zurückgeben aus Rekursiver Funktion

Verfasst: Di Jan 10, 2012 4:56 pm
von cloidnerux
Woran liegt das?
Das deine Variable Zähler nie erhöht wird. Vlt solltest du sie als Pointer übergeben?

Re: 2 Variablen zurückgeben aus Rekursiver Funktion

Verfasst: Di Jan 10, 2012 8:20 pm
von DANrulz81
Wieso wird diese nicht erhöht? Ich dachte, dass die Funktion sich selbst aufruft und somit

Code: Alles auswählen

return collatz(3*start + 1, zaehler++);
zaehler erhöht wird.

Re: 2 Variablen zurückgeben aus Rekursiver Funktion

Verfasst: Di Jan 10, 2012 8:42 pm
von cloidnerux
Wieso wird diese nicht erhöht? Ich dachte, dass die Funktion sich selbst aufruft und somit
Weil du hier etwas hast, was sich "Call by Value" nennt.
Dabei werden Variablen, die du übergibst, kopiert.
Daher übergibst du zwar jeweils einen Wert, aber deine Orginalvariable wird nicht verändert.
Wenn du dies ändern willst, musst du einen Pointer übergeben. So wird zwar auch der Pointer kopiert, aber da er auf eine bestimmte Variable zeigt, nämlich die in der main, wird auch eben diese inkrementiert.

Re: 2 Variablen zurückgeben aus Rekursiver Funktion

Verfasst: Di Jan 10, 2012 10:01 pm
von DANrulz81
O.k. Das hab ich mal versucht, so wie ich es verstanden habe, leider ohne Erfolg:

Code: Alles auswählen

#include <stdio.h>

int collatz(int start, int *zeiger)
{
        if ( (start == 1) || (start == -1) ) {
                return 1;
        }
        printf("\n%i",start);
        if (start%2)
        {
                return collatz(3*start + 1,zeiger++);
        }
        else
        {
                return collatz(start / 2,zeiger++);
        }
}

int main(void)
{
    int start=0,zaehler=0;
    int *zeiger;

    zeiger=&zaehler;

    printf("\nBitte geben sie eine Startzahl ein: ");
    scanf("%i",&start);

    collatz(start,zeiger);
    printf("\n1");
    printf("\n\nAnzahl der Durchg\x84nge: %i",*zeiger);

    return 0;
}
:(

Re: 2 Variablen zurückgeben aus Rekursiver Funktion

Verfasst: Di Jan 10, 2012 10:14 pm
von cloidnerux
Es müsste (*zeiger)++ heißen

Re: 2 Variablen zurückgeben aus Rekursiver Funktion

Verfasst: Di Jan 10, 2012 10:24 pm
von DANrulz81
Es müsste (*zeiger)++ heißen
So klappt das leider auch nicht.

Ich bekomme folgende Compilerausgabe:

Code: Alles auswählen

C:\Users\dennis\Programme\C-Prgrammierung\Collatz1.c||In function 'collatz':|
C:\Users\dennis\Programme\C-Prgrammierung\Collatz1.c|11|warning: passing argument 2 of 'collatz' makes pointer from integer without a cast|
C:\Users\dennis\Programme\C-Prgrammierung\Collatz1.c|3|note: expected 'int *' but argument is of type 'int'|
C:\Users\dennis\Programme\C-Prgrammierung\Collatz1.c|15|warning: passing argument 2 of 'collatz' makes pointer from integer without a cast|
C:\Users\dennis\Programme\C-Prgrammierung\Collatz1.c|3|note: expected 'int *' but argument is of type 'int'|
||=== Build finished: 0 errors, 2 warnings ===|

Re: 2 Variablen zurückgeben aus Rekursiver Funktion

Verfasst: Di Jan 10, 2012 10:28 pm
von cloidnerux
Ok, nochmal in vollständig:
return collatz(3*start + 1,zeiger++);
Musst du erweitern auf:

Code: Alles auswählen

(*zeiger)++;
return collatz(3*start + 1,zeiger);
Mit dem * greifst du auf das ziel des Zeigers zu und erhöhst es dann.
Dann kannst du den Pointer übergeben.
In einer Zeile geht das meines Wissens nach nicht.

Re: 2 Variablen zurückgeben aus Rekursiver Funktion

Verfasst: Di Jan 10, 2012 10:32 pm
von DANrulz81
Du bist der Beste :o

Wie steht der Zeiger in Klammern beim Inkrement? Das versteh ich nicht ganz.

Re: 2 Variablen zurückgeben aus Rekursiver Funktion

Verfasst: Di Jan 10, 2012 10:58 pm
von cloidnerux
Wie steht der Zeiger in Klammern beim Inkrement? Das versteh ich nicht ganz.
Klammern bedeuten in C und C++ nur "Kapselung", daher der Inhalt IN den Klammern wird vor dem außen herum bearbeitet(dies ist aber nicht überall möglich).
So versuche ich mögliche Unklarheiten sofort zu umgehen, denn der Ausdruck kann auf 2 Arten Interpretiert werden:

Code: Alles auswählen

*zeiger++;  //Ohne klammern
*(zeiger++); Variante A
(*zeiger)++;  //Variante B
Beim ersten wird der Die Speicheradresse des Zeigers erhöht, beim zweiten den Inhalt der Variable auf die gezeigt wird. Wahrscheinlich wird der Compiler Variante B wählen, da ich mir aber nicht sicher war, hab ich eben die Klammern genutzt um es zu verdeutlichen.