Wie kann man diesen Code verschönern bzw. eleganter schreiben
-
Ich habe hier ein kleines Programm geschrieben und den vorherigen Code
so umgebaut, dass nun eine Funktion für die Berechnung und eine weitere für die Ausgabe benutzt wird.Damit man nicht zu viele Parameter übergeben muss, habe ich dann noch ein Struct gebaut, dass ich nun hier auch bei der Parameterübergabe nutzen kann.
Da ich zu viele Parameter für eine Funktion als unschön empfinde.Des Weiteren habe ich für die Ausgabe von 3 Namen ein Chararray verwendet in dem die Namen gespeichert werden um auch hier den Code schöner aussehen zu lassen.
Nun würde ich nun noch gerne wissen, was ich sonst noch tun könnte,
damit der Code schöner und eleganter wird.Das im Code mit Ganzzahlen gerechnet wird ist so gewollt, so genau brauche ich das nämlich nicht.
Hier der Code:
#include <stdio.h> #include <math.h> /* Credits */ #define AKTUELL 46 #define BASE (60-AKTUELL) #define SNIPER 19 #define LASER 75 typedef struct Object{ const long int paket; // Credits pro Paket const long int paketzeit; // Paketzeit long int raffinerien; // Anzahl Raffinerien long int paketproduktion; // Raffinerien * Paket long int prod; // globale Produktion pro Stunde long int timer; long int kosten; // Kosten des Forschungsgegenstands } Object; /* Berechne Zeit bis ausreichend Credits gewonnen wurden */ long int calc(struct Object *mObject){ long int summe = 0; long int stundenzahler = 0; do { summe += mObject->prod; if ( stundenzahler == mObject->paketzeit) { summe += mObject->paketproduktion; stundenzahler = 0; } mObject->timer++; } while (summe < mObject->kosten); return summe; } void ausgabe(struct Object *mObject, const char* name, long int summe){ printf("%s:\n", name); printf(" In %li Stunden erreicht der Zähler die erforderlichen Credits\n", mObject->timer); printf(" Summe = %li\n", summe); printf(" Zielsumme = %li\n", mObject->kosten); printf(" Dies sind %li Tage und %li Stunden\n", mObject->timer/24, mObject->timer-24*(mObject->timer/24)); } int main(){ const char *str[] = { "Basis", "Scharfschuetze", "Laser" }; long int summe = 0; // Object mObject; Object mObject = { .paket = 38623, .paketzeit = 6 }; /* Bis zur neuen Base */ mObject.prod = 160488; mObject.raffinerien = 13; mObject.paketproduktion = mObject.raffinerien * mObject.paket; mObject.timer = 0; mObject.kosten = BASE * pow(10, 6); summe = calc(&mObject); ausgabe(&mObject, str[0], summe); /* Neue Base ist fertig */ mObject.prod += 50000; // Aenderung durch neue Basis mObject.raffinerien += 5; // Aenderung durch neue Basis /* Bis zum Scharfschuetze */ mObject.paketproduktion = mObject.raffinerien * mObject.paket; // Raffinerien * Paket mObject.timer = 0; mObject.kosten = SNIPER * pow(10, 6); summe = calc(&mObject); ausgabe(&mObject, str[0], summe); /* Bis zum Laser */ mObject.paketproduktion = mObject.raffinerien * mObject.paket; // Raffinerien * Paket mObject.timer = 0; mObject.kosten = LASER * pow(10, 6); summe = calc(&mObject); ausgabe(&mObject, str[0], summe); return 0; }
Kann man an diesem Code noch etwas verbessern, verschönern oder noch eleganter machen?
Und falls man den Code komplett neu schreiben würde, wie würdet ihr das lösen bzw. machen wenn die Sprache C und der Sprachstandard C99 vorgeschrieben sein soll?
Geht das irgendwie noch eleganter, schöner und besser?Und was haltet ihr generell von meinem Code, ist der gut/schön?
Was würdet ihr diesem von einer Skala von 1 bis 10 geben, wobei 10 die Bestnote wäre?
Und falls der nicht gut ist, was stört euch an ihm?
-
Wenn du schon den ersten Schritt zur Objektorientierung gegangen bist, würde ich auch noch weiter gehen. Beispiel:
mObject.raffinerien = 13; mObject.paketproduktion = mObject.raffinerien * mObject.paket;
Das ist sehr unschön. paketproduktion ist durch das, was es repräsentieren soll, schon auf den Wert von raffinerien * paket festegelegt. Das ist der einzig sinnvolle Wert und der muss auch so zugewiesen werden, sonst funktioniert das Programm nicht. Trotzdem wird dem Benutzer des Objekts überlassen, diesen Wert korrekt zu setzen. Er könnte es falsch machen. Oder vergessen. Dann funktioniert das Objekt nicht mehr.
Daher würde ich an der Stelle lieber so etwas wie
set_raffinerien(&mObject, 13);
sehen (oder auch andere sinnvolle Initialisierungsfunktionen).
Wenn du die Interna des Objekts komplett wegPIMPLst, dann ist sogar ausgeschlossen, dass der Benutzer das Objekt falsch benutzt.
Das
calc
undausgabe
sind jetzt schon praktisch "Member"funktionen des structs, das ist also kein großer Sprung, das Konzept komplett durchzuziehen.P.S.: Const-correctness bei
ausgabe
beachten!
-
Danke für deinen Vorschlag, ich werden diesen gleich mal versuchen umzusetzen.
-
Und für pow(10, 6); fällt dir bestimmt auch was besseres ein.*
1E6
oder1000000L
.
Auch als#define MEGA 1000000L
*Die Compiler können mittlerweile solche Konstanten erkennen, die über Funktionen mit festen Parametern erzeugt werden, und sparen den Funktionsaufruf.
Aber du wolltest doch keine Fließkommazahlen. Und es ist auch unnötig