C - Code entcplusplusifizierung



  • Hallo erstmal an alle!
    Ich habe hier schon manche Dinge zu meinem kleinen Spiel namens "Pong", das ich
    für die Schule im Moment schreibe, nachgefragt. Nun habe ich das Programm fertig -
    gestellt. Da wir das ganze in einem Programm namens "Pelles C" (welches ein reiner C - Compiler anscheinend ist)
    kompilieren können sollen und ich mit Visual Studio gearbeitet habe, habe ich nun ein Problem :D.
    Ich habe versucht den kompletten Code in reinem C zu halten, jedoch gibt er mir tausend Fehler aus wenn ich den Code versuche in "Pelles C" zu kompilieren.
    Das fängt schon mit einem "struct" am Anfang an und naja :D.
    Nun zur eigentlichen Frage. Ich habe das ganze mal hochgeladen und ich würde
    mich freuen, wenn ein paar von euch das kurz anschauen, auch wenn es nur eine
    Methode oder ein paar Zeilen sind und ihr mir dann sagen könntet was denn da "nicht C" sein könnte und vielleicht einen eventuellen Lösungsvorschlag.
    Bin echt ratlos und bekomme das nicht hin! Danke schon mal!
    (Bitte nicht zu kritisch sein ich bin blutiger Anfänger!!! :P)

    http://pastebin.com/Tt6UiHJ5



  • Also dass #pragma regio, #include <conio.h> und #include <windows.h> kein Standard C sind sollte klar sein.
    bool könnte Probleme machen.
    Sämtliche Methoden. (C kennt keine Funktionen in Strukturen, nur freie Funktionen!)
    C kennt keine Referenzen, nur Pointer.
    Bei function style cast bin ich mir auch nicht sicher, probier's mal mit (float)f;

    Aber wenn du bei VS mit .c und nicht mit .cpp Dateien gearbeitet hättest, hätte der das meiste davon auch nicht durchgehen lassen.



  • klar das mit der #pragma regin usw. ist klar.
    Bool macht tatsächlich Probleme, jedoch werde ich diese Variable sowieso streichen.
    Eine der Hauptfragen wäre jetzt für mich, was
    soll aus der struct werden? Und findet jemand noch weitere wichtige Dinge?


  • Mod

    Eine class (oder struct) mit Membermethoden, zum Beispiel

    class foo
    {
     char member;
     void bar(char foobar) {member = foobar;}
    };
    

    ist in C++ bloß die Syntaxzuckerschreibweise für das C-Äquivalent

    typedef struct
    {
     char member;
    } foo;
    
    void bar(foo* this, char foobar)
    {
     this->member = foobar;
    }
    

    Im Prinzip kannst du so deine Klassen nach C übersetzen. Aufpassen musst du jedoch bei den automatisch aufgerufenen Memberfunktionen, wie dem Konstruktor von ball. Hier hast du noch Glück, dass ball keinen Standardkonsturktor hat und du die Konstruktoraufrufe daher explizit im Code sehen kannst (und nach obigem Schema übersetzen). Bei Klassen mit einem Standardkonstruktor (oder Klassen mit einem nicht-trivialen Destruktor) musst du im Code aufpassen, wo die Objekte erzeugt/zerstört werden. Dort würde ein C++-Compiler automatisch einen passenden Konstruktor-/Destruktoraufruf setzen, den man so direkt nicht im Code sieht. Den musst du in C dann natürlich von Hand aufrufen.



  • Du hättest auch von Anfang an mit dem Visual Studio in purem C programmieren können. :p



  • Nicht können sondern sollen, zumal die Aufgabenstellung mit Pelles C ja wohl klar war:

    Hier ein C Port, wobei einige offensichtliche Fehler wie

    float x = 2,5;
    und
    if(ende=false)
    

    schon mal rausgeflogen sind.

    http://ideone.com/yr9LgX



  • Danke schon mal soweit! Der Code von Wutz plus diese Variablen umändern funktioniert soweit. Ich bekomme jetzt nur noch 2 Errors.

    POLINK: error: Unresolved external symbol '__imp_GetAsyncKeyState'.
    POLINK: fatal error: 1 unresolved external(s).

    Was bedeuten diese?


  • Mod

    blackevil673 schrieb:

    Danke schon mal soweit! Der Code von Wutz plus diese Variablen umändern funktioniert soweit. Ich bekomme jetzt nur noch 2 Errors.

    POLINK: error: Unresolved external symbol '__imp_GetAsyncKeyState'.
    POLINK: fatal error: 1 unresolved external(s).

    Was bedeuten diese?

    Du hast die passende Library für diese Winapi-Funktion nicht dazu gelinkt:
    http://msdn.microsoft.com/en-us/library/windows/desktop/ms646293(v=vs.85).aspx



  • So. Ich krame den Post nochmal hervor, da ich nun dank eurer übrigens echt tollen Hilfe!
    nun mein kleines Pong Spiel fertig gestellt habe. Allerdings denke ich, dass ich viele
    Sachen aufgrund meines begrenzten Wissens in diesen Bereichen einfach sehr unpraktisch gelöst habe.
    Daher habe ich den fertigen Code noch einmal hochgeladen, und würde mir wünschen, dass einige
    von euch eben dort reinschauen und mir vllt. ein paar Tipps geben könnten, was verbesserungswürdig
    bzw. einfacher zu lösen gewesen wäre und am besten auch einen Ansatz wie das dann funktioniert!
    Danke schon einmal!!!

    http://ideone.com/mcKSSB
    (thx @ Wutz für diese Seite!)



  • würde mich wirklich über eine Rückmeldung von irgend jemandem freuen, da ich mich schließlich weiter verbessern will und das doch ein relativ guter Weg ist denke ich...



  • Ich hab nur mal flüchtig drüber geschaut. Ist mir zuviel Windows dabei. 😉

    Bei der Auswahl nimmst du statt 49 oder 50 gleich '1' oder '2'.
    Das ist schließlich das, was du auch willst und es ist besser lesbar.

    Wenn du viele gleichartig Variablen hast, die siech nur in Ziffern untercheiden (str1, str2, str3 ..., schwierigkeit1, ...), dann nimm gleich ein Array.
    Ja, es gibt auch 2D-Arrays

    Ich weiß nicht was du in highscoreEinlesen veranstaltest, aber es ist eindeutig zu kompliziert.

    Zu einem Highscore gehört ein Name und ein Wert. Das kommt in eine struct, daraus ein Array.
    Das kannst du dann auch mit qsort sortieren.

    Wenn du Programmcode hast, der mehr als zweimal vorkommt, mach daraus eine Funktion.
    Schau mal in highscoreAusgeben. 5 mal der Selbe Kram, der sich nur im Dateinamen unterscheidet.

    Feste absolute Pfade, die auch nich im Wurzelverzeichnis von C: stehen sind absolut inakzeptabel. Als Nichtadmin hat man da nict unbedingt Schreibrechte.

    Alles in deutsch und dann "Press Space bar ..." 🙄



  • Das mit den 50 und '2' gilt natürlich auch für 65 und 'A' und andere Zeichen.

    Wenn du ein Array wie name hast (Zeile 13), dann kann das niemals NULL werden (Zeile 546). Das ist ein Array und kein Zeiger.
    Es kann höchstens leer sein. Dann lautet der Test aber *name != 0

    Zuviele globale Variablen.
    Wenn du menu einen Return-Wert spendierst, kannst du z.B. mainloop verzichten.

    Bei += (float)(b.x - comp.x) / 3; brauchst du den cast nicht, wenn du 3.0 schreibst.



  • okay ich habe nun die 50 usw. zu '1' geändert, den cast weggelassen, das mit dem name = NULL verbessert
    und eine extra Funktion für highscoreAusgeben() geschrieben. Was ich nicht ganz verstehe ist, was du mit

    Wenn du viele gleichartig Variablen hast, die siech nur in Ziffern untercheiden (str1, str2, str3 ..., schwierigkeit1, ...), dann nimm gleich ein Array.
    Ja, es gibt auch 2D-Arrays

    meinst und was ich nun genau für Dateipfade am besten wählen sollte 😕



  • Statt

    char schwierigkeit1[20] = "Amateur";                                            
                    char schwierigkeit2[20] = "Machbar";
                    char schwierigkeit3[20] = "Veteran";                                            // Strings zum Vergleich der Schwierigkeiten initialisieren
                    char schwierigkeit4[20] = "Nervt\224tend";
    

    gibt es

    char schwierigkeitn[][20] = {"Amateur", "Machbar", "Veteran", "Nervt\224tend" ""};
    // und noch
    float posoffset[] = { 5, 2, 2, 5, 0};
    

    Dann kannst du es

    if (GetAsyncKeyState(links))                                                            // falls ja, fragen ob die Taste die in "links" gespeichert ist, gedrückt wurde
    { for (int i; schwierigkeitn[i][0] != 0;i++)
        if(strcmp(schwierigkeit,schwierigkeitn[i]) == 0)                   // falls ja, schwierigkeitsgrad vergleichen, um die passende Bewegungsgeschwindigkeit der Pads zu wählen
                            {
                                    you.x -= posoffset[i];
                            }
    

    Besser noch due merkst dir nicht den Text vom Schwierigkeitsgrad sondern gleich den Index

    if (GetAsyncKeyState(links))                                                            // falls ja, fragen ob die Taste die in "links" gespeichert ist, gedrückt wurde
    { you.x -= posoffset[Schwierigkeitsindex];
    }
    

    Wenn du dann noch die Bezeichnung und den Offset in eine struct packst, hast du beides zusammen.

    Du hast mehrmals you.x += 2,5; geschrieben. Schau dir mal das Zeichen zwischen 2 und 5 an. Das ist nicht das, was du möchtest.

    Es gibt von Microsoft Vorgaben wo solche Daten abgelegt werden sollen.
    Die kenne ich aber nicht. Wäre mal ne Suche/Nachfrage im WinAPI-Unterforum wert.



  • - wiederkehrende Funktionalitäten verlagert man in Funktionen, und ruft die dann mehrfach (mit unterschiedl. Parametern) auf anstatt Code zu kopieren
    - Modularisierung schafft ebenso einen besseren Überblick in deinem Programm, z.B. könnte man alle Datei-Bearbeitungen in ein eigenes Modul auslagern
    - auf Zeichen außerhalb von Basis-ASCII verzichten ("Nervt\224tend" usw.)


Anmelden zum Antworten