In endlos-schleife gefallen

Vierundachzig

Cadet 1st Year
Registriert
Dez. 2015
Beiträge
10
Hallo zusammen,
ich hab mich erst seit wenigen wochen mit C auseinander gesetzt und zerbreche mir bei einer Aufgabe den Kopf.
Ich muss eine Funktion erstellen, die eine Zahl in zahlen zerlegt. Diese funktion wird dann durch eine while schleife aufgerufen.
Ich bekomme unendlich 2en als print raus und weiß einfach nicht, woran das liegen könnte.
Vielleicht könnt ihr mir ja helfen, hier der Quellcode:

(eingabe) geteilt wurde, wird damit weitergearbeitet

C:
#include <stdio.h>


    int dreier= 2;
    int zweifach= 0;


    if(zweifach== 0){
        zweifach= eingabe;
    }

      
                        eingabe = eingabe;
                        return = dreier;
                        return dreier;
                }  
           

           

                    return -1;}
    int tei
                    return -1;}
    int zahl= 2;
    int zweifach= 0;
zähler = 2;
    int zahl= 0;

               
        }
}
}


int main() {


    }
 
Zuletzt bearbeitet:
Bitte nutze den Code-Tag. Sonst tut sich das keiner an
 
Kompiliert das Ding denn überhaupt?
Bei primfaktor geht doch mindestens eine geschweifte Klammer mehr auf als zu.

Außerdem wenn primfaktor(1) aufgerufen wird, dann ist eingabe == 1 => welcher return wird denn hier überhaupt ausgeführt? Also selbst wenn der Code so funktioniert, da fehlt in der Funktion dann definitiv ein return block für Fälle mit eingabe <= 2.

Ohne return ist das Verhalten der Funktion evtl. nicht definiert und dir kann keiner sagen wieso du 2 bekommst wenn es keinen Rückgabewert gibt.
 
  • Gefällt mir
Reaktionen: FranzvonAssisi
Du hast kein Return, soweit ich das sehe. Das resultiert in undefibiertem Verhalten -> "da kann alles passieren"

Primfaktor(1) -> Eingabe = 1 -> Eingabe < 2

Oder ist der kopierte Code evtl. Fehlerhaft? Da sind so ein paar komische Sachen...

Lg
 
Da fehlt irgendwo eine Klammer und es ist nicht ganz klar, wo die Eingabe letztendlich herkommt, aber while ( ( pf = primfaktor (1) ) > 1) ist in dem Fall immer wahr.
 
KingLz schrieb:
Kompiliert das Ding denn überhaupt?
Bei primfaktor geht doch mindestens eine geschweifte Klammer mehr auf als zu.

Außerdem wenn primfaktor(1) aufgerufen wird, dann ist eingabe == 1 => welcher return wird denn hier überhaupt ausgeführt? Also selbst wenn der Code so funktioniert, da fehlt in der Funktion dann definitiv ein return block für Fälle mit eingabe <= 2.

Ohne return ist das Verhalten der Funktion evtl. nicht definiert und dir kann keiner sagen wieso du 2 bekommst wenn es keinen Rückgabewert gibt.
Schreibfehler, soll primfaktor(12) sein statt primfaktor(1).
Jetzt bin ich immer noch in der endlosschleife, aber diesmal mit 6 statt 2.
Kann gut sein dass dort eine klammer zu viel drin ist, hab die ganzen nutzlosen kommentare von mir weggemacht und dabei vielleicht eine klammer vergessen

Als return will ich ja den teiler bekommen, damit alle Primzahlen aufgelistet werden, also in zweile 21
 
Bitte vollständig und korrekt den Quellcode kopieren und sauber formatieren. Wie schon gesagt wurde fehlt eine Klammer, aber durch die mangelhafte Formatierung ist es nicht erkennbar welche das ist.
 
Dieser Block returned nur ein einziges Mal:

C:
while(eingabe % teiler == 0){

    eingabe = eingabe / teiler;

    teiler = eingabe;

    return teiler;

}

Wenn Eingabe 12 ist, dann wird die for Schleife mit Teiler = 2 ausgeführt.
2 teilt 12, die Whileschleife wird also einmalig ausgeführt.
eingabe = 6, teiler = eingabe, teiler wird returned => du bekommst eine 6 als Ausgabe.

Da immer nur mit eingabe gearbeitet wird, aber nie mit letzte (wie es evtl gedacht ist), so bekommst du nur 6er.
Da eine Funktion nur einmalig returnen kann, kannst du dir returns in Schleifen auch sparen und direkt if Anweisungen verwenden. (wenn man mehrmals returnen kann kenn ich die C Version in der dies geht nicht)

Ich denke du musst da irgendwo eingabe mit letzte tauschen und letzte auch mal neu schreiben dann kommt man irgendwie zum Ergebnis. ;)
 
Zuletzt bearbeitet:
C:
    while ( ( pf = primfaktor (12) ) > 1)
    printf( "%d\n" , pf ) ;
Diese Schleife wird unendlich oft ausgeführt, da die Bedingung immer identisch ist.
 
Amaoto schrieb:
C:
    while ( ( pf = primfaktor (12) ) > 1)
    printf( "%d\n" , pf ) ;
Diese Schleife wird unendlich oft ausgeführt, da die Bedingung immer identisch ist.

Die Variable letzte ist als statisch definiert. Ich vermute die Idee ist, dass anhand dieser aufrufübergreifenden Variable die Funktion bei gleicher Eingabe trotzdem andere Werte liefern soll. Letzte ist also effektiv eine 2. Eingabe.
 
KingLz schrieb:
Die Variable letzte ist als statisch definiert. Ich vermute die Idee ist, dass anhand dieser aufrufübergreifenden Variable die Funktion bei gleicher Eingabe trotzdem andere Werte liefern soll. Letzte ist also effektiv eine 2. Eingabe.
Ja richtig, wenn ich zum beispiel 12 teile dann hab ich 2 als ersten primfaktor und möchte dann mit 6 weiterarbeiten.

Bei
while(eingabe % teiler == 0){
eingabe = eingabe / teiler;
teiler = eingabe;
return teiler;
}
hab ich noch einen Fehler, da sollte eigentlich letzte = eingabe statt teiler stehen, hab das auch korrigiert.
Jetzt bekomme ich allerdings gar keine ausgabe, was mich noch mehr verwirrt :freak:
 
Der ganze Algorithmus ist mir schleierhaft. Die for- und while-Schleifen werden bei jedem Funktionsaufruf mit denselben Parametern gestartet und werden meiner Meinung nach stets zum selben Ergebnis kommen, weil der statische Parameter letzte zwar gesetzt wird, aber keinerlei Einfluss auf den Start der Schleifen bzw deren Ende hat. Demnach müsste letzte daher immer wieder bei 6 landen und der returnwert stets 2.

Übrigens : Es wäre schön, wenn du den Code anständig einrückst...
 
Aufruf1: eingabe=12 ; letzte = 12 ==> return teiler (2 aus der 1. Iteration der for-Schleife)
Aufruf2: eingabe=12 ; letzte = 6 ==> return teiler (2 aus der 1. Iteration der for-Schleife)
Aufruf3: eingabe=12 ; letzte = 3 ==> return teiler (3 aus der 2. Iteration der for-Schleife)

Output:
2
2
3

Primfaktorzerlegung von 12 = 2 * 2 * 3
Ergänzung ()

Vierundachzig schrieb:
Huch? Was los? Das sah für mich so aus als wenn es hätte funktionieren müssen?
 
Zuletzt bearbeitet:
Genau, der Code funktioniert. Ist zwar immer noch schlecht formatiert und uneinheitlich, aber liefert das korrekte Ergebnis. Ich habe mal die Formatierung vereinheitlicht ...

C:
#include <stdio.h>

int primfaktor(int eingabe) {

    int teiler = 2;
    static int letzte = 0;

    if(letzte == 0) {
        letzte = eingabe;
    }
    else {
        eingabe = letzte;
    }

    if(eingabe > 2) {
        for(teiler = 2; teiler <= eingabe; teiler++) {
            while(eingabe % teiler == 0) {
                eingabe = eingabe / teiler;
                letzte = eingabe;
                return teiler;
            }
            if(letzte == 1) {
                return -1;
            }          
        }
    }
    else {
        return -2;
    }
}

int main() {

    int pf ;
    while((pf = primfaktor (12)) > 1) {
        printf("%d\n" , pf);
    }
    return 0;
}

Man kann den Code übrigens auch online auf der Seite http://codepad.org/ testen.
 
Zuletzt bearbeitet: (Link angepasst)
Mit Rekursion kann man hier übrigens einiges an Code einsparen. Da ich nicht weiß in welchem Rahmen sich diese Aufgabe bewegt, möchte ich die Lösung jedoch noch nicht darstellen, da nicht klar ist ob es sich hier um Hausaufgaben im weitesten Sinne handelt.

An dieser Stelle daher nur eine kurze Umschreibung was Rekursion bedeutet:

Rekursion bezieht sich darauf, dass sich eine Funktion selbst aufruft. Im vorliegenden Quellcode wird die Funktion primfaktor durch die While-Schleife in der main() aufgerufen bis die Abbruchbedingung erfüllt ist. Dadurch, dass hier eine static-Variable innerhalb der Funktion zum Einsatz kommt, ist von außen nicht wirklich ersichtlich, dass die While-Schleife überhaupt ein Ende hat, weil sich augenscheinlich nichts an der Abbruchbedingung ändert.
Man kann die "Schleife" bzw. die Abbruchbedingung auch innerhalb der Funktion realisieren, indem die Funktion sich selbst mit dem neuen Wert aufruft, sobald ein Teiler gefunden wurde.

In etwa so:

--> Suche kleinsten Teiler größer 1 von 12
----> 2
------> Suche kleinsten Teiler größer 1 von 12/2=6
--------> 2
----------> Suche kleinsten Teiler größer 1 von 6/2=3
------------> 3
--------------> Suche kleinsten Teiler größer 1 von 3/3=1
----------------> Ende

In dieser Form wäre die Funktion primfaktor nur ca. halb so lang, übersichtlicher und man vermeidet die "versteckte" Abbruchbedingung in der While-Schleife.
 
  • Gefällt mir
Reaktionen: FranzvonAssisi
Kann mich mal bitte jemand aufklaeren was der Sinn von der while Schleife ist? Die wird doch genau einmal ausgefuehrt und dann die gesamte Funktion verlassen, oder nicht?
 
Sie ruft solange die Funktion primfaktor() auf und gibt den zurückgegebenen Funktionswert aus, bis der Funktionswert kleiner gleich 1 ist. Bei dem Wert 12 sind das genau 3 Aufrufe.

Deutlicher wird es, wenn man das anders schreibt:
C:
    int pf = primfaktor (12);
    while(pf > 1) {
        printf("%d\n" , pf);
        pf = primfaktor (12);
    }
 
Zuletzt bearbeitet:
@Raijin Genau das dachte ich auch.

Mit Rekursion hast du das in ein paar Zeilen erledigt...

Ist zwar unter Umständen minimal weniger performant, aber das sollte nicht stören...

Lg
 
Zurück
Oben