Initialisierung von Variablen unter C

  • C

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von Gonger96.

    Initialisierung von Variablen unter C

    Hey Leute,

    im Studium lernen wir momentan C. Jedoch habe ich immer desöfteren Fehler gehabt, obwohl mein Code laut Logik 100% laufen müsste.
    Habe lange gebraucht um dies herauszufinden, woran es liegt.

    Hier ein Beispiel (Aufgabe):

    Ganzzahlige rechtwinklige Dreiecke

    Es gibt rechtwinklige Dreiecke (d.h. Dreiecke für die der Satz des Pythagoras gilt), deren Seitenlängen alle ganze Zah-
    len sind.
    •Schreiben Sie ein Programm, das alle diese Dreiecke in Form der Längen ihrer drei Seiten findet
    und diese drei Seitenlängen für jedes gefundene Dreieck ausgibt. Hierbei sollen nur Seitenlängen, die nicht größer als 500
    sind, berücksichtigt werden.
    •Geben Sie zusätzlich die Anzahl der gefundenen Dreiecke aus.
    •Hinweis: Nutzen Sie drei geschachtelte for-Schleifen, die alle Möglichkeiten durchprobieren. Diese Vorge-hensweise ist ein Beispiel für eine sogenannte "Brute Force"-Methode.


    Hier mein Code dazu:

    C-Quellcode

    1. #include <stdio.h>
    2. int main(void)
    3. {
    4. system("cls");
    5. printf_s("Berechnung von rechtwinkligen Dreiecken bis a,b,c <= 500!\n");
    6. printf_s("\n");
    7. printf_s("Zum Starten Taste druecken...");
    8. getch();
    9. system("cls");
    10. const int MAX_SEITE = 500;
    11. int a,b,c,i;
    12. i = 0; //Auskommentieren für Fehlfunktion
    13. for(a = 1; a <= MAX_SEITE ; a++)
    14. {
    15. for(b = 1; b <= MAX_SEITE ; b++)
    16. {
    17. for(c = 1; c <= MAX_SEITE ; c++)
    18. {
    19. if((c*c) == (a*a) + (b*b))
    20. {
    21. printf_s("Seitenl\x84ngen: a = %d; b = %d, c = %d;\n",a,b,c);
    22. i++;
    23. }
    24. }
    25. }
    26. }
    27. printf_s("\n");
    28. printf_s("%d Dreiecke gefunden!\n",i);
    29. getch();
    30. return 0;
    31. }



    So wie es hier steht funktioniert das Programm. Kommentiert man jedoch die oben genannte Zeile "i = 0;" aus, dann kommt als Anzahl der Dreiecke eine unrealistische Zahl heraus...

    Jetzt frage ich mich, woher er die Intialisierungszahl für i bei "int i;" herbekommt und warum man zwingend i auf 0 setzen muss.


    Viele Grüße,


    Michael
    @Thunderbolt Jou.

    MB-Tech schrieb:

    eine unrealistische Zahl heraus...
    Falls Du schon mal .NET programmiert hast (egal, ob VB.NET oder C#) oder frühere VB-Versionen, hast Du Dir möglicherweise angewöhnt anzunehmen, dass alle Variablen mit Null oder einem Leer-Initializer vorinitialisiert werden.
    Dies ist in C / C++ (nicht aber CLI) nicht der Fall, da bekommt eine Variable eine Adresse im Speicher zugewiesen, und da steht dann halt irgendeine Bitkombination drin, die da irgendwoher kommt.
    Die musst Du in jedem Falle Deinem Programm entsprechend initialisieren.
    Die Laufvariablen Deiner For-Schleifen initialisierst Du ja auch in den for-Zeilen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Falls Du schon mal .NET programmiert hast (egal, ob VB.NET oder C#) oder frühere VB-Versionen, hast Du Dir möglicherweise angewöhnt anzunehmen, dass alle Variablen mit Null oder einem Leer-Initializer vorinitialisiert werden.


    Ja, genau das dachte ich.

    ErfinderDesRades schrieb:

    eiglich von 0 an loszählen lassen
    Nö, weil reguläre Dreiecke immer Seitenlängen von 1 an aufwärts haben.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Mal abgesehen davon, dass das sehr sehr sehr BruteForce ist.
    b muss (sollte) bei a anfangen (nicht bei 1) und c bei b. Sonst hst du später die Permutationen deiner Dreieckslängentripel (äh, ja) alle vorhanden (bspw. (3,4,5) und (4,3,5) und so weiter). Desweiteren kann man sich (wenn man etwas von bf weg will) die dritte for-Schleife schenken. Du rechnest einfach c mit a und b aus, und prüfst ob c ein int ist. blöd ausgedrückt, prüfen ob Math.Floor(c) == c ist.
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ThePlexian“ ()

    Da er die Brute Force Methode ja explizit benutzen soll, sollte er bei den drei Schleifen bleiben. Außerdem kann man darüber streiten, ob die Dreiecke (3, 4, 5) und (4, 3, 5) tatsächlich die selben Dreiecke sind, oder eben nicht. Es ist schließlich nach Dreiecken und nicht nach Dreieckslängenkombinationen gefragt. Ist zwar ziemlich spitzfindig, verändert jedoch das Ergebnis (die Anzahl der Dreiecke).
    @Jörg Du scheinst einen falschen Begriff von BruteForce im Kopf zu haben ;) BF ist nichts schlimmes, es beschreibt nur, ein Problem mit "roher Gewalt" (brute force eben) zu lösen. Das heißt man probiert einfach alle Kombinationen durch, anstatt sich einen gescheiten Algo zu überlegen.
    Ob man nur BF beim Suchen von rechtw. Dreiecken mit ganzzahligen Seiten nutzt, oder zum Herausfinden eines Passwortes, da schlagen die Boardregeln ;)
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais
    Ok @ThePlexian aber könnte diese Möglichkeit nicht alle Türen für Schadsoftware in Diesem Forum öffnen ???
    Ich persönlich finde das eher unter dem Thema " Bitte nicht " einzuordnen
    :D Ein Programm sollte nicht nur Hand und Fuß, sondern auch Herz und Hirn haben. (Michael Anton) :D

    MFG Jörg ;)

    Muss jeder vermeintliche Programmierer ne Signatur haben ??
    Ich bin mir gerade nicht sicher, ob du a) einen Troll aufrecht hälst oder b) das Ganze ernst meinst.
    Falls a) -> Chapeau :D
    Falls b) -> Brute Force bedeutet nichts anderes, als jede Möglichkeit auszuprobieren. Wenn ich nen Freund besuche und nur die Straße kenne, in der er wohnt, dann wäre die Brute-Force Methode an jeder einzelnen Tür zu klingen, bis er hinter einer steht, während es deutlich klüger wäre ihn entweder anzurufen oder an der ersten Türe konkret nach seiner Adresse zu fragen. Und eine Möglichkeit, ein mir unbekanntes Passwort zu ermitteln, ist, alle möglichen Kombinationen auszuprobieren, daher heißt diese Methode auch Brute-Force und hat diesen Namen bekannt gemacht.
    Ich bin seit 12.November 2012 in Diesen Forum ;)
    Nein ich bin kein Troll und werde sowas auch nicht aufrechterhalten!!!!!!!!!
    Solltest Du ein Problem haben Junge komm vorbei dann klären Wir das ;)
    :D Ein Programm sollte nicht nur Hand und Fuß, sondern auch Herz und Hirn haben. (Michael Anton) :D

    MFG Jörg ;)

    Muss jeder vermeintliche Programmierer ne Signatur haben ??

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Jörg“ ()

    Vielen Dank noch einmal für die ausführliche Diskussion zu rechtwinkligen Dreiecken :)

    Mir wäre eher eine Diskussion über Bit´s und Byte´s in Bezug auf meine Frage lieber gewesen, warum es gerade in C so ist und nicht anders...
    C/++ ist eine nicht verwaltete native Sprache. Das heißt, dass das, was in der Datei steht auch so im RAM landet. Variablen werden in dem Segment .bss (uninitialisierter Speicher) abgelegt, um keinen/wenig Platz in der Datei zu verbrauchen. Das sind dann also Zeiger, die auf eine Speicherstelle zeigen. Wenn da ein Programm vorher Daten abgelegt hat, sind diese Daten in deiner Variable gespeichert. .NET initialisiert primitive Datentypen für dich. C/++ macht dies nicht, sondern nur das, was du explizit möchtest (Quellcode).

    Weiterführender Link: en.wikipedia.org/wiki/Uninitialized_variable
    Mit freundlichen Grüßen,
    Thunderbolt
    Du meinst das?

    MB-Tech schrieb:

    Jetzt frage ich mich, woher er die Intialisierungszahl für i bei "int i;" herbekommt und warum man zwingend i auf 0 setzen muss.
    Musst du nicht, du kannst es auch auf 1 setzen.
    Oder auf 9
    oder 42
    oder...
    (Aber 0 ist in diesem Fall ganz sinnvoll, denn am Anfang, wenn die Dreiecke noch nicht gezählt sind, ist die Anzahl ja 0.)

    Jdfs. wenn du i nicht initialisierst, dann hats halt irgendeinen Wert, und offenbar sogar von mal zu mal einen anneren.
    Bei C ist das so, weil C C ist und nicht C++ oder vb.net .

    C ist eine sehr rohe Sprache, die nicht viel Brimborium macht. Etwa kennt es ueberhaupt keine Strings, sondern nur Chars, und um Text auszugeben musste halt ein Array von Chars ausgeben.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    MB-Tech schrieb:

    warum es gerade in C so ist
    C ist halt so definiert.
    Du kannst im Quellcode ein Array instanziieren, das wird zur Compilezeit gemacht, und wenn Du denselben Quellcode mit unterschiedlich großen Arrays schreibst, wird die Exe unterschiedlich lang sein.
    In C++ geht dies (ob in C auch, weiß ich nicht):

    C-Quellcode

    1. int array1[10]; // da steht Grütze drin
    2. int array2[10] = {0}; // alle Elemente sind 0
    3. int array3[10] = {1}; // das 1. Element ist 1, alle weiteren sind 0
    4. int array4[10] = {0, 1, 2, 3, 4, 5, 6, 7, 78, 9}; // die Elemente sind mit 0 ... 9 belegt

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!