Problem: Unterprogramme und NST

Cherry07

Mitglied
Hallo,
bin gerade dabei einen Code zuschreiben der mittels eines Itervallhalbierungsverfahren die Nullstellen von verschiedenen Funktionen berechnen soll.
Das Problem dabei ist, dass der Code nicht richtig funktioniert und ich zudem noch ein Anfänger bin und nicht recht weiss wo das Problemchen liegt.

Würd mich sehr freuen, wenn mir mal jemand behilflich sein kann.
Danke.

Gruß
cherry07

Aufgabenstellung ist die folgende:
TA a) Funktion f mit reellen Parameter x, die im Rumpf die Fkts. enthält,
TA b) Funktion nullstelle (erhaelt als Eingabe die Intervalle u. d. Genauigkeit) und
TA c) main-Funktion zur Ausgabe der Ergebnisse
zu schreiben.

Hier mal mein C-Code:

Code:
# include <stdio.h>
# include <stdlib.h>
# include <math.h>

// TA a)

int fn;            //globale Variable

double f(double x)
{         
    double ergebnis;
           
           switch (fn)
           {
                  case 1: ergebnis = sin(x);
                          break;
                          
                  case 2: ergebnis = ((double)exp(x))-(5*x)+1;
                          break;
                          
                  case 3: ergebnis = (x*x)-2;
                          break;
                          
                  case 4: ergebnis = (1/7)+(1/x);
                          break;
                          
                  case 5: ergebnis = (2*x)-2;
                          break;
                          
                 default: printf("Fehler bei der Eingabe.\n");
                          break;
           }     
return ergebnis;
}

// TA b)

double nullstelle(double a, double b, double g) 
{ 
       int *anzit=0;     //Ausgabe der Iterationschritte
       int ok=1;     //Variable für Wahrheitswerte true and false
       double x0;    //später zur Berechnung von f(x0) falls ok = 1 ist
       double c;
       
       do
       {
            c=(a+b)/2;
            
            if((f(a)<0 && f(b)>0) || (f(a)>0 && f(b)<0))
            {
                       if(f(c)>0)
                       {
                                 //a=a;
                                 c=b;
                       }
                       
                       if(f(c)<0)
                       {
                                //b=b;
                                c=a;          
                       }
                       
                       if(f(a)==0)
                       {
                                  c=b=a; //x0=a     
                       }
                       
                       if(f(b)==0)
                       {
                                  c=a=b; //x0=b    
                       }
            }                       
       }
       while((c<(g)) && (ok!=1));       
       *anzit++;
       x0=c;
}

// TA c)

int main (void)
{
    int fn;
    double x0, x;
    double a, b, g;
    
    
    printf("Zur Auswahl einer Funktion f, geben Sie bitte eine Zahl zwischen 1 und 5 ein.\n");
	scanf("%d", &fn);

	printf("Geben Sie die Intervallgrenze a ein: ");
	scanf("%lf", &a);

	printf("Geben Sie die Intervallgrenze b ein: ");
	scanf("%lf", &b);

	printf("Geben Sie die Genauigkeit an: ");
	scanf("%lf", &g);

    // Ergebnis:
    nullstelle(a, b, g); //Funktionsaufruf
   
       printf("Ergebnis der ausgewaehlten Funktion ist: %lf\n", f(x));
       printf("f(x0) = %lf\n", f(x0));
       printf("Anzahl der Iterationsschritte: %d\n", &anzit);

	system ("pause");
	return 0;
}
 
Zuletzt bearbeitet:
Das direkte Problem dürfte die doppelte Deklaration von fn sein. Die hast du oben als globale Variable, aber auch unten in main nochmal. Nimm die unten raus.

x0 mußt du auch global machen, wenn du den Wert außerhalb der Funktion wiederhaben willst.

Noch ein Tip: Auch wenn es sinnlos erscheint, nie Variablen uninitialisiert rumliegen lassen; immer gleich bei der Definition auf einen Default-Wert (z.Bsp.0) setzen.
 
Mir ist noch aufgefallen, dass du "anzit" aus der "main" aufrufst, obwohl die Variable nur innerhalb der Funktion "nullstelle" gültig ist. Außerdem ist die Art, wie du "anzit" als Zeiger verwendest falsch. Für deinen Zweck brauchst du "anzit" auch nicht als Zeiger. Eine normale int-Variable genügt.

Die Funktion f gibt einen double Wert zurück. Fließkommazahlen sollte man grundsätzlich nie auf Gleichheit überprüfen. Das kommt, weil Fließkommazahlen im Rechner mit dem Binärsystem nur ungenau dargestellt werden könnnen. Stattdessen sollte man auf einen kleinen Bereich um die Nullstelle rum überprüfen. Also:
Code:
double epsilon = 0.001;
if (  ( f(a) > -epsilon ) && ( f(a) < epsilon ) )
 

Neue Beiträge

Zurück