Fragen zu meinem Programm



  • ich muss für die Uni ein Programm in C schreiben. bis auf die Formatierung klappte es auch schon so wie es soll (berechnung von Polynomen mit Horner). Wollte nur mal nett Fragen ob es so Ok ist oder was mann noch besser machen kann.

    Schon mal ein großes DANKE an alle.

    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <conio.h>
    
    typedef struct Listenelement 
    		{
    			double Wert;
    			struct Listenelement *next;
    		}	t_Listenelement;
    
    double horner(t_Listenelement*, double , int );	//Prototyp
    double leseZahl(int, int);                  //Prototyp
    
    void main(void)
    {
    	int i,n;
    	double x0, Ergebnis;
    	t_Listenelement *start, *p, *pneu;
    
    	printf("x0: ");
    	x0 = leseZahl(2,2);
    
    	printf("\nAnzahl: ");
    	n = leseZahl(0,1);
    
    	p = (t_Listenelement *) malloc (sizeof (t_Listenelement));
    	printf("\nBitte geben Sie die 0 Zahl ein: ",n);
    	p->Wert = leseZahl(2,2);
    
    	start = p;
    
    	for (i=0;i<n;i++)
    	{	
    		struct Listenelement *ptr = NULL;
    		pneu = (t_Listenelement *) malloc (sizeof (t_Listenelement));
    		p->next = pneu;
    		printf("\nBitte geben Sie die %i Zahl ein: ", i+1);
    		pneu->Wert = leseZahl(2,2);
    		p = pneu;
    	}
    
    	Ergebnis = horner(start, x0, n);
    	printf("\nDie Zahl lautet %.2f\n", Ergebnis);
    
    	for (i=0; i<n; i++)
    	{
    		printf("\nDie Zahl lautet %.2f", start->Wert);
    		start = start->next;
    	}
    }//Ende main
    
    double horner(t_Listenelement *a, double x0, int n)
    { 
    	double h;
    	if(n>0) h=horner(a->next, x0, n-1); else return a->Wert;
    	return h*x0+a->Wert;
    }//Ende horner
    
    double leseZahl(int Zahlenbereich, int Vorzeichen)
    /*	Zahlenbereich:	0 nur ganze Zahlen
    					1 Gleitkommazahlen
    	Vorzeichen:		0 nur negative Zahlen
    					1 nur positive Zahlen
    					2 positive und negative Zahlen
    */
    {
        char ctext[10]={0};				//Array mit 10 Feldern
        char cwert;						//Variable zum Zwischenspeichern
        int ipos=0,ikont=0,iMinus;		//Variable zur steuerung des Array und zur Bewertung der Eingabe
    
    	if (Vorzeichen == 0 || Vorzeichen == 1)
    	{
    		iMinus = 1;
    		if (Vorzeichen == 0)
    		{
    			ipos++;
    			ctext[0]="-";
                printf("%c",ctext[0]);
    		}
    	}
    	else
    	{
    		iMinus = 0;
    	}
    
    	if (Zahlenbereich == 0)
    	{
    		ikont = 1;
    	}
    	else
    	{
    		ikont = 0;
    	}
    
        while(ipos!=10)
        {
            fflush(stdin);				//startet die Berechnung mit den bis jetzt eingelesenen Werten nach drücken von Enter
            if(cwert==13)
            {   
                break;
            }
    		if(cwert==8&&ipos>0)		//if - Schleife ermöglicht das Löschen des jeweilig letzten Wertes im Array
    		{
    			ipos--;
    			if(ctext[ipos]=046 && Zahlenbereich != 0)		//ermöglicht die erneute eingabe eines Punktes oder Kommas nach dem Löschen eines solchen
    			{
    				if(ipos==0 && Vorzeichen != 1)
    				{
    					iMinus=0;
    				}
    				ikont=0;
    			}
    			ctext[ipos]=000;
    			printf("\b \b");
    		}
            cwert=getch();
            if((cwert>='0'&&cwert<='9')||(cwert=='.'&&ikont==0)||(cwert==','&&ikont==0)||(cwert=='-'&&iMinus==0))   //lässt nur die Zeichen "1" bis "9" sowie "." und "," und "-"zu
            {                                           
    			if(cwert=='.'||cwert==',')		//bei Eingabe eines Komma wird dieses in einen Punkt umgewandelt
                {
                    ikont=1;
                    if(cwert==',')		//if - Schleife wandelt ein evt. eingegebenes Komma in einen Punkt um
                    {
                        cwert='.';			
                    }
                }
                ctext[ipos]=cwert;
                printf("%c",cwert);
    			iMinus=1;
                ipos++;
            }
        } //while - Schleife  
       return(atof(ctext));				//Rückgabe (entspricht der eingelesenen Zahl)
    } //leseZahl
    


  • Hm, wenn du ANSI C programmierst darfst du soweit ich weiß keine conio.h hernehmen...

    Und ob dein Programm so ok ist musst du wissen. Führs aus und schau obs das richtige tut 😉



  • ein bisschen optimierung?
    alles sauber einruecken und

    tags benutzen waer ein anfang ;)
    [cpp]if (Zahlenbereich == 0)
    {
       ikont = 1;
    }
    else
    {
       ikont = 0;
    }
    

    wird zu

    ikont = !Zahlenbereich;
    

    versuch aehnliches mal an weiteren stellen. der code wird dadurch nicht unlesbar sondern nur kompakter und schneller zu lesen.



  • Schon mal Danke, das Programm muss nicht in ANSI C geschrieben sein und es geht mir auch nicht um die Funktion, die tut was sie soll. Es geht mir ehr um so Tipps wie mit dem einrücken und den Tags um meinen Code sauberer und effizienter zu bekommen oder anderweitig zu verbessern.

    Danke



  • return ist keine funktion. gewoehn dich an den anblick von return 0;
    sizeof ist auch keine funktion, sondern ein operator. es ist also vollkommen okay, sizeof somearray irgendwo zu lesen. hier siehst du auch die prioritaet des sizeof operators.

    main() hat bitte immer den returntyp int.

    es schadet zwar nicht, den returnwert von malloc() zu casten, aber du musst es nicht machen. bei zu vielen casts kann die uebersichtlichkeit leiden und eventuell unterdrueckst du so warnungen, die dir das leben leichter machen koennten (typen gibts immerhin nicht grundlos).

    zuweisungen lassen sich verketten. grund: die zuweisung ist eine operation wie jede andere (addition, etc...).

    int a,b; a = b = 10; b = (a = 20);
    

    genau das kann anfaengern zum verhaengnis werden, wenn sie in einem vergleich statt einem == ein einfaches = benutzen. deshalb siehst du oft lustige vergleiche wie if (SUCCESS == result). sollte man da aus versehen eine zuweisung versuchen, gibts nen fehler. die schreibweise sehe ich persoenlich eher als kruecke fuer anfaenger an. wer coden lernen will, muss eben aufpassen und mit wachem verstand coden. dann passieren solche "tippfehler" schon garnicht erst. immer sofort das lesen und checken, was man codet (und oft compilieren und testen).

    vergleiche gegen 0 (foo==0) lassen sich kuerzer als !foo schreiben. manche anfaenger machen auch den "fehler", sowas zu schreiben, obwohl der vergleich zu true redundant ist:

    if (foo == true)... // unsinn!
    

    vergleiche lassen sich auch direkt zuweisen.

    /* schlecht */ if (foo) bar = 1; else bar = 0;
    /* besser   */ bar = (foo); /* bar muss nicht 0 oder 1 sein, weil nicht-null auch als wahr definiert ist */
    


  • mit return ist keine Funktion meist du folgende Zeile???

    return(atof(ctext));
    

    wenn ja wie soll ich es dann machen? Über einen Zeiger, welchen ich mit an die Funktion übergebe?

    Habe gleich noch eine Frage, meine Funktion lese Zahl soll je nach Übergabe eine ganze Zahl (int) oder eine Gleitpunktzahl (double) liefern. Ist es egal das ich den Int-Wert als double übergebe und einen Datenverlust riskiere (Compiler Meldung), welcher ja nur theo. auftreten kann?

    Danke



  • so:

    return atof(ctext);
    

    doubles haben 52 bit genauigkeit (rest ist vorzeichen und exponent). das ist ausreichend fuer alle 32 bit ints. rundungsfehler in den aeusseren bereichen sind jedoch nicht auszuschliessen.



  • Danke für die schnelle Antwort, es ist klar das ein int in ein double passt aber ist das auch Ok sprich sauber oder sollte man es anders Coden.



  • also sauber ist wirklich was anderes, da geb ich dir recht. man koennte das mit einer union regeln. eine union ist quasi wie ein struct, jedoch belegen alle members der union den gleichen platz:

    union foostruct {
      int a;
      double b;
    } foo;
    foo.a = 10;
    foo.b = 123.4;
    /* foo.a ist jetzt zugemuellt mit daten von b */
    

    du kannst dann ein struct zurueckgeben, dass ein typenflag und eine union enthaelt.


Anmelden zum Antworten