Mein erstes Programm

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
kaputtnix
Beiträge: 3
Registriert: Mi Jul 30, 2008 9:18 pm

Mein erstes Programm

Beitrag von kaputtnix » Mi Jul 30, 2008 10:57 pm

so, in meiner vorstellung bereits erwähnt: hiermit veröffentlich ich mein erstes c-programm, nutzung/verbreitung gestattet/erwünscht :lol:

was kann das prog: dezimalzahlen(10er-sytem) in beliebiges anderes system umwandeln(binär-hexadezimal)

funtionsweise: kern ist die standart "kopfrechenweise" zur umwandlung dezimalsystem -> beliebigses anderes zahlensystem (vorkomma: dezimalzahl / #system...ergebnis nur in nazürlichen zahlen....rest = ziffer im "beliebiges system" (von rechts nach links)......(ergebnis ohne rest) / system......naja und so weiter...rechnweise ist denke ich jedem bekannt)

wieso dieses programm: naja, man sieht schnell, dass man oft auch in anderen, als geläufiges dezimal, zahlensystemen arbeiten muss....daher die idee.

zur entstehung: ansporn war wie erwähnt das tutorial auf tutorials.at. nach durcharbeitung der ersten 3 kapitel wurde der erste spatenstich gesetzt, als erstes war nur ganzzahlen von dezimal -> binär, erweiterung auf dezimal -> sytem nach wahl, hinzufügen des rechengangs für nachkommastellen(6-stellen genauigkeit)


der code:

Code: Alles auswählen

#include <stdio.h>
#include <conio.h>



int main()
{
    int sys, rund, rund2, rest, rdy = 2, k;
    int x[40], y[5], i, j;
    float dezi1, dezi2, ein, kom;

    printf("%53s","Zahlensystem Umrechner\n\n");
    printf("%72s","Aus dem Dezimal in Binaer bis Hexadezimal System umrechnen\n\n\n");

    do
    {
        while(rdy == 2)      /*systemwahl*/
        {
            printf("System waehlen(z.B. 2=binaer, 8=oktal, etc): ");
            fflush(stdin);
            scanf("%d", &sys);
            if((sys > 16) || (sys < 2))     /*check gültiges zahlensystem*/
            printf("Ungueltige Wahl. Waehlen sie eine Zahl von 2 bis 16.\n");
            else rdy = 1;
        }
        printf("\nDezimalzahl eingeben: ");
        fflush(stdin);
        scanf("%f", &dezi1);
        ein = dezi1;
        rund2 = ein;
        kom = (ein - ((float)rund2));
        for(j = 0; j <= 5; j++) y[j] = 0; j = 0;       /*elemente vom y-array auf 0  initialisieren, j den wert 0 geben*/
        for(i = 0; i <= 40; i++) x[i] = 0; i = 0;       /*elemente vom x-array auf 0  initialisieren, i den wert 0 geben*/
        do      /*rechengang vorkomma*/
        {
            dezi2 = (dezi1 / sys);
            rund = dezi2;
            if(dezi2 != rund)       /*wenn rest*/
            {
                rest = (dezi1 - (rund * sys));
                dezi1 = rund;
                x[i] = rest;
                i++;
            }
            else        /*kein rest*/
            {
                dezi1 = rund;
                x[i] = 0;
                i++;
            }
        }
        while(dezi1 > 0);       /*ende des rechengangs, wenn bei der teilung wert < 1 rauskommt*/
        if(rund2 != ein)
        {
            do      /*rechengang nachkomma*/
            {
                kom = (kom * sys);
                rund = kom;
                y[j] = rund;
                kom = (kom - rund);
                j++;
            }
            while(j <= 5);

        }
        printf("\nDie Zahl %.3f entspricht im %d-er System:\n", ein, sys);       /*ergebnisausgabe*/

        for(i = 40, k= 0; i >= 0; i--)     /*ergebnisausgabe(vorkomma)*/
        {
            if(x[i] == 0 && k != 1)         /*überflüssige nullen am anfang des ergebnisses wegstreichen*/
            {                               /*erst wenn das nächst niedrigere feld(x[i-1]) des arrays einen*/
                if(x[i-1] != 0) k = 1;      /*wert != 0 hat, kommt bis ende der schleife nurnoch else(ergebnisausgabe)*/
            }
            else
            {
                if(x[i] < 10) printf("%d", x[i]);       /*ausgabe ansich, festlegung der ziffern A-F*/
                if(x[i] == 10) printf("A");
                if(x[i] == 11) printf("B");
                if(x[i] == 12) printf("C");
                if(x[i] == 13) printf("D");
                if(x[i] == 14) printf("E");
                if(x[i] == 15) printf("F");
            }
        }
        if(rund2 != ein)        /*ergebnisausgabe(nachkomma)*/
        {
            printf(".");
            for(j = 0; j <=5; j++)
            {
                if(y[j] < 10) printf("%d", y[j]);
                if(y[j] == 10) printf("A");
                if(y[j] == 11) printf("B");
                if(y[j] == 12) printf("C");
                if(y[j] == 13) printf("D");
                if(y[j] == 14) printf("E");
                if(y[j] == 15) printf("F");
            }
        }
        printf("\n\nWeitere Berrechnung?\n(1) Ja\n(2) Ja, aber anderes System\n(3) Nein\t\t\tIhre Wahl: ");
        fflush(stdin);
        scanf("%d", &rdy);
        for(;(rdy > 3)  || (rdy < 1);)
        {
             printf("Ungueltige Wahl.\n");
             printf("\nWeitere Berrechnung?\n(1) Ja\n(2) Ja, aber anderes System\n(3) Nein\t\t\tIhre Wahl: ");
             fflush(stdin);
             scanf("%d", &rdy);
        }
    }
    while(rdy != 3);        /* beenden durch benutzer(durch wahl)*/

    return 0;

}
so, meine fragen dazu nun:
1. sagen wir, ich möchte zb die zahl 77777777 in beliebiges zahlensytem umwandeln....berechenet wird mir immer dir zahl 77777776(ist nur beispiel, bei >7stellige zahlen kommt das mit der "rundung" öftest vor). habe ich irgendwo falschen zahlentyp gewähl? "float" müsste doch eigentlich die erwünschte genauigkeit bringen, oder nich? erste überlegnung meinerseits war:weil ich für die (ab)gerundetet zahl (variablen rund, rund2) typ int benutzt habe kommt eine ungenauigkeit zusatande ( genauerer zahlentyp -> ungenauerer zahlentyp -> evtl genauigkeitsverlust(so wars doch oder?^^)). diese vermutung hab ich dann aber recht schnell wieder verworfen da mir in der ergebnisausgabe (die zahl "***" entspricht im #-system,....") ja eine nie benutze/geänderet float variable ausgegeben wird und diese trotz allem den "gerundeten" wert ausgibt.

2. was sagt ihr punkto übersichtlichkeit code? mal ausgenommen dass ich evtl ein paar überflüssige variablen initialisiert habe, sprich: man das selbe ergebnis mit weniger variablen bekommen hätte. ist wie gesagt mein erstes prog und durch erweiterungen (dez-binär -> dez-beliebig -> dez-beliebig-nachkomma) ist das ganze ein wenig auseinander geraten. ziel war es auch eigentlich erstmal nur erworbene kenntnisse anzuwenden(grundbefehle, scheifen, arrays(womit ich, 3.kapitel war ich wie gesagt, probleme hatte), syntax allgemein, ...) ....nicht ein "marktfähiges" :lol: programm zu schreiben.

3. iwelche sonstigen kritiken/ratschläge


gruß
kaputtnix

ps: urteilt nich zu hart, "ist mein erster tag" :lol:

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8860
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Mein erstes Programm

Beitrag von Xin » Mi Jul 30, 2008 11:34 pm

kaputtnix hat geschrieben:zur entstehung: ansporn war wie erwähnt das tutorial auf tutorials.at. nach durcharbeitung der ersten 3 kapitel wurde der erste spatenstich gesetzt, als erstes war nur ganzzahlen von dezimal -> binär, erweiterung auf dezimal -> sytem nach wahl, hinzufügen des rechengangs für nachkommastellen(6-stellen genauigkeit)
Wenn das Dein erstes eigenes Programm ist, dann Hut ab.
kaputtnix hat geschrieben: 1. sagen wir, ich möchte zb die zahl 77777777 in beliebiges zahlensytem umwandeln....berechenet wird mir immer dir zahl 77777776(ist nur beispiel, bei >7stellige zahlen kommt das mit der "rundung" öftest vor). habe ich irgendwo falschen zahlentyp gewähl? "float" müsste doch eigentlich die erwünschte genauigkeit bringen, oder nich?
Float ist 32 Bit breit, aber die Mantisse ist nur 23 Bit. 23 Bit entspricht einer Genauigkeit von ca. 1/8000000. Du bewegst Dich also sehr grenzwertig. Nimm Double (64 Bit breit, 53 Bit Mantisse)
kaputtnix hat geschrieben:2. was sagt ihr punkto übersichtlichkeit code?
Die Formatierung kann verbessert werden, schon alleine durch Leerzeichen, kann man Abschnitte blocken und damit den Code besser Strukturieren. Dafür gibt es Leerzeilen, die zusammenhängendes trennen.

Die Variablennamen sind mir unverständlich. Was heißt rdy? Ich sehe es aus dem Code, aber ich weiß nicht, was rdy heißt.

Du hast Redundanz drin, und die Zuordnung zu den Hexadezimalen Zahlen könnte man kürzen, statt reihenweise ifs würde ein switch helfen oder noch besser eine Rechnung.
kaputtnix hat geschrieben:ziel war es auch eigentlich erstmal nur erworbene kenntnisse anzuwenden(grundbefehle, scheifen, arrays(womit ich, 3.kapitel war ich wie gesagt, probleme hatte), syntax allgemein, ...) ....nicht ein "marktfähiges" :lol: programm zu schreiben.
Schon klar, ist auch recht gut für einen Einstieg. Fast schon zu gut.


Schluss für heute... Akku leer. Feierabend :-)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: Mein erstes Programm

Beitrag von fat-lobyte » Do Jul 31, 2008 8:49 am

Hallo, das ist schon ein ziemlich gutes Programm für einen Anfänger. Auch die Formatierung ist überraschend gut.
Meinen glückwunsch, dein Einstieg in die Programmierung ist gut gelungen ;-)

So, und nachdem du wahrscheinlich besser werden willst, wäre es vielleicht gut ein paar Kritikpunkte anzubringen. Ist nichts persönliches und schmälert nicht deine Leistung, sind nur ein paar dinge, die du vielleicht anders machen solltest:

kaputtnix hat geschrieben:

Code: Alles auswählen

printf("%72s","Aus dem Dezimal in Binaer bis Hexadezimal System umrechnen\n\n\n");
"%72s" ??? Ist das legal? Was tut das? Hast du die Zeichen abgezählt? Ich wäre dazu zu faul gewesen und hätte einfach nur "%s" geschrieben. Aber das hätte das gleiche ergebnis geliefert.
kaputtnix hat geschrieben:

Code: Alles auswählen

int sys, rund, rund2, rest, rdy = 2, k;
Benenne deine Variablen so, dass man versteht was sie bedeuten. Kann sein, dass du zu Faul zum tippen bist (sind wir alle ;) ), aber bei größeren Programmen kennst du dich dann überhaupt nicht mehr aus was welche Variable war.
Außerdem wäre es gut, wenn du Variablen, die nicht unbedingt "in eine Gruppe" gehören, getrennt deklarierst, am besten noch mit kommentar dazu.
Ungefähr so:

Code: Alles auswählen

int sys; /**< Diese variable tut etwas*/
int rund, rund2; /**< Diese zwei machen auch was. */
int rest; /**< Die braucht man für etwas */
...
kaputtnix hat geschrieben:

Code: Alles auswählen

for(j = 0; j <= 5; j++) y[j] = 0; j = 0;       /*elemente vom y-array auf 0  initialisieren, j den wert 0 geben*/
for(i = 0; i <= 40; i++) x[i] = 0; i = 0;       /*elemente vom x-array auf 0  initialisieren, i den wert 0 geben*/
Sieh dir mal die funktion "memset()" in einer Referenz an, z.B. hier.
kaputtnix hat geschrieben:

Code: Alles auswählen

            while(rdy == 2)      /*systemwahl*/
            {
                printf("System waehlen(z.B. 2=binaer, 8=oktal, etc): ");
                fflush(stdin);
                scanf("%d", &sys);
                if((sys > 16) || (sys < 2))     /*check gültiges zahlensystem*/
                    printf("Ungueltige Wahl. Waehlen sie eine Zahl von 2 bis 16.\n");
                else rdy = 1;
            }
Autch :?
Bitte lies die FAQ Frage 2, was das fflush(stdin); betrifft. (Nebenbei könntest du die Frage bewerten und dann in den Vorschlagsthread schreiben, ob das gut erklärt ist oder nicht. Rechtschreibfehler bitte auch melden.)
kaputtnix hat geschrieben:

Code: Alles auswählen

rund2 = ein;
Du musst wissen, dass bei einer Konvertierung von floating point auf integer nicht "gerundet" wird, sondern einfach nur die nachkommastellen abgeschnitten. Wenn du wirklich runden willst, verwende ceil() und floor() aus der Standardbibliothek.

kaputtnix hat geschrieben:

Code: Alles auswählen

                if(dezi2 != rund)       /*wenn rest*/
BÖSE! operator==() und operator!=() sollte man grundsätzlich nicht mit Floating Point Zahlen verwenden, denn eine Floating point zahl mit begrenzter anzahl von stellen kann niemals eine Reele Zahl genau speichern, es geht immer etwas durch Rundungfehler verloren. Deswegen kann ein solcher vergleich nur durch "Glück" wahr sein.
kaputtnix hat geschrieben:

Code: Alles auswählen

if(dezi2 != rund)
{
    rest = (dezi1 - (rund * sys));
    dezi1 = rund;
}
Schon mal was vom "Modulo" operator gehört?

Code: Alles auswählen

rest = dezi1 % sys;
kaputtnix hat geschrieben: mal ausgenommen dass ich evtl ein paar überflüssige variablen initialisiert habe, sprich: man das selbe ergebnis mit weniger variablen bekommen hätte.
Ja, das stimmt. Schlaf ne nacht drüber, dann sieh dir den Code nochmal an und du wirst sehen, dass du viele Variablen einfach nicht brauchst.

Zur formatierung:
Die ist schon recht gut, allerdings wäre es gut wenn du zusammenhängende Codeteile "Gruppieren" könntest, und nicht zusammengehörige durch ein Newline trennen. Es ist viel besser zu viel Platz zwischen den anweisungen zu lassen, als zuwenig.


Ansonsten generell ziemlich gut. Allerdings sind noch ein paar Redundanzen drinnen, und der Algorithmus enthält viel "Optimierungspotenzial" und er könnte viel allgemeiner geschrieben werden.
Aber das wird dir später auffallen, wenn du schon besser Programmieren kannst und das Programm nochmals ansiehst.
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Mein erstes Programm

Beitrag von Kerli » Do Jul 31, 2008 10:41 am

fat-lobyte hat geschrieben:Du musst wissen, dass bei einer Konvertierung von floating point auf integer nicht "gerundet" wird, sondern einfach nur die nachkommastellen abgeschnitten. Wenn du wirklich runden willst, verwende ceil() und floor() aus der Standardbibliothek.
Da gibt es auch einen einfachen Trick, bei dem man ausnützt, dass die Nachkommastellen abgeschnitten werden. Einfach 0.5 dazuaddieren und dann zu einer Ganzzahl konvertieren runded korrekt kaufmännisch, wie man es normalerweise gerne hätte.
Also zb:

Code: Alles auswählen

float genauer_wert = 14.56;
int gerundet = genauer_wert + 0.5f; // gerundet = 14.56 + 0.5 = 15.06 -> 15
Eigentlich wieder was für die FAQ...
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Antworten