Berechnung Integral.... wo hängt der Fehler ???
-
Moinsen,
Bevor ich hier meinen Quelltext poste, kurz worum es geht: Mit Hilfe der Trapezregel soll ein Integral der Funktion f ausgerechnet werden. Hierbei gibt meine Funktion f() die Werte y für die Funktion stuetz() aus. Hinzu kommt die Funktion teilsum() die einen Teil der benötigten y Werte zusammenfasst.
Das soll jetzt aber nicht abschrecken, da mir das Programm schon in der input Funktion abstürzt... muss irgendeine Zeiger/Feld Überschreitung sein (weiß ich leider nicht so genau, da ich mich noch niht so lange mit c befasse).
Noch was erläuterndes:
K = Max. Grad des Polynoms und somit der Koeffizienten für K+1
k = eingegebener Grad
n = Die Stützstellen der Funktion, also die "Abgrenzung" der Flächenstücke
testweise auf 20 festgelegt
a[] = KoeffizientenAlso hier mal der Quellcode ... wäre nett, wenn mir wer weiter helfen könnte:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>#define K 100
#define n 20double a[K+1];
int k;double f(double x)
{
double sum = 0.0;
int i;
for(i=0;i<=k;i++)
{
printf("Die Funktion f wird für x%i ausgefuehrt!",i);
sum += a[i] * pow(x,i);
}
return sum;}
void stuetz(double xa,double H,int nst,double *y)
{
int i;
for(i=0;i<=nst-1;i++)
{
printf("Berechnung y%i",i);
y[i] = f(xa + i * H);
}
return;}
double teilsum(int anf,int ende,double *y)
{
int i;
double teilsumme = 0.0;
for(i=anf;i<=ende;i++)
{
printf("Die Teilsumme wird berechnet!");
teilsumme += y[i];
}
return teilsumme;}
void input(double *a)
{
int i;
printf("Bitte geben Sie nun die Werte der Koeffizienten (a) ein: ");
for(i=0;i<=k;i++)
{
printf("\nGeben Sie den Wert fuer a%i ein: ",i);
scanf("%lf",&a[i]);
return;
}}
int main(void)
{
double F,H,xa,xe,y[n];printf("Bitte geben Sie den Grad des Polynoms ein ein (0-100): ");
scanf("%lf",&k);
printf("Bitte geben Sie die untere Schranke des Integrals ein xa: ");
scanf("%lf",&xa);
printf("Bitte geben Sie die obere Schranke des Integrals ein xe: ");
scanf("%lf",&xe);
input(a);
H = (xe - xa) / (n - 1);
stuetz(xa,H,n,y);
F = (H/2) * (y[0] + y[n-1] + 2 * teilsum(1,n-2,y));
printf("Die Berechnung des Integrals ergibt: %lf",F);return 0;
}
-
Blöd eingefügt, ich mach es noch mal im c-code:
#include <stdio.h> #include <stdlib.h> #include <math.h> #define K 100 #define n 20 double a[K+1]; int k; double f(double x) { double sum = 0.0; int i; for(i=0;i<=k;i++) { //printf("Die Funktion f wird für x%i ausgefuehrt!",i); sum += a[i] * pow(x,i); } return sum; } void stuetz(double xa,double H,int nst,double *y) { int i; for(i=0;i<=nst-1;i++) { //printf("Berechnung y%i",i); y[i] = f(xa + i * H); } return; } double teilsum(int anf,int ende,double *y) { int i; double teilsumme = 0.0; for(i=anf;i<=ende;i++) { //printf("Die Teilsumme wird berechnet!"); teilsumme += y[i]; } return teilsumme; } void input(double *a) { int i; printf("Bitte geben Sie nun die Werte der Koeffizienten (a) ein: "); for(i=0;i<=k;i++) { printf("\nGeben Sie den Wert fuer a%i ein: ",i); scanf("%lf",&a[i]); return; } } int main(void) { double F,H,xa,xe,y[n]; printf("Bitte geben Sie den Grad des Polynoms ein ein (0-100): "); scanf("%lf",&k); printf("Bitte geben Sie die untere Schranke des Integrals ein xa: "); scanf("%lf",&xa); printf("Bitte geben Sie die obere Schranke des Integrals ein xe: "); scanf("%lf",&xe); input(a); H = (xe - xa) / (n - 1); stuetz(xa,H,n,y); F = (H/2) * (y[0] + y[n-1] + 2 * teilsum(1,n-2,y)); printf("Die Berechnung des Integrals ergibt: %lf",F); return 0; }
-
Hi,
das return ist in die for-schleife gerutscht (in input()) - höchstwahrscheinlich möchtest du ja k+1 Koeffizienten einlesen und nicht nach dem ersten raus, oder?Ansonsten: Der Grad des Polynoms - k wird als double in eine int-variable eingelesen, da solltest %d anstatt dem %lf verwenden.
Das wars dann aber auch schon - dann tut das proggy bei mir auf den ersten Blick wunderbar. Speicherzugriffsfehler gabs bei mir jetzt keine - ausser ich geb nen Grad > 100 und entsprechend viele Koeffizienten - das wird noch nicht geprüft.grüße
-
du liest k als double ein, hast es aber als int deklariert..
ausserdem übergibst du der input funktion die adresse von deinbem feld a, das is sinnlos weil das feld eh global deklariert ist, also brauchst du das gar net...
und, dein hauptproblem, in der input funktion is dein return an der falschen stelle, in der schleife ist es eindeutig falsch positioniert
-
Erstmal vielen Danke, dass ihr mir so schnell geantwortet habt. Es sind echt meistens die kleinen Dinge, die man übersieht.
@ Sepp: Hab nochmal ne Frage zum Typ der k Variablen. Und zwar dachte ich immer, dass %lf für long float steht und somit double repräsentiert. Ich werde es aber nochmal mit %d probieren.
Muss dann nur noch gucken, ob auch wirklich das rauskommt, was mit der Taschenrechner sagt... mit den vielen Indeces ist das recht unübersichtlich.
MfG
Micha
-
@ Kleine Hilfe: Hm... was soll ich denn nach input() übergeben. Ich sehe ein, dass es durch die globale Deklaration nicht so sinnvoll ist, a zu übergeben, da es schon vorhanden ist. Soll ich in der main function einfach input(); schreiben .... werd mich mal probieren
-
Ja, %lf steht für double - aber die Variable "k" (die du im Hauptprogramm abfragst) ist ein int, da brauchst du %d.
und das Array würde ich an deiner Stelle innerhalb der main() definieren, die Koeffizientenzahl übrigens auch:
void input(double* arr,int size) { ... } int main() { double F,H,xa,xe,y[n],a[K+1]; int k; ... fscanf("%d",&k); input(a,k); ... }
(nächste Verbesserung wäre es, a dynamisch per malloc() zu reservieren)
-
Blöder Fehler mit dem k .... bei den ganzen Indeces komm ich schnell durch einander. Klar ist k ein int und muss dem entsprechend übergeben werden. Mit Malloc haben wir noch nicht gearbeitet... aber evtl lerne ich das dann auch nochmal.
Vielen Dank an alle
-
elduderado schrieb:
Blöder Fehler mit dem k .... bei den ganzen Indeces komm ich schnell durch einander.
Und deshalb ist es immer eine gute Idee, den Variablen sinnvolle Namen zu geben. (C unterstützt nicht umsonst die Möglichkeit, (fast) beliebig lange Namen zu definieren ;))
-
Oha, ich muss meinen Post doch nochmal heraus wühlen. Erstmal worums geht, dazu die main func:
int main(void) { double F,H,xa,xe,y[n]; char neu; do { do { printf("Bitte geben Sie den Grad des Polynoms ein (0-100): "); scanf("%i",&k); }while(k>100); printf("Bitte geben Sie die untere Schranke des Integrals ein xa: "); scanf("%lf",&xa); printf("Bitte geben Sie die obere Schranke des Integrals ein xe: "); scanf("%lf",&xe); input(a); H = (xe - xa) / (n - 1); stuetz(xa,H,n,y); F = (H/2) * (y[0] + y[n-1] + 2 * teilsum(1,n-2,y)); printf("Die Berechnung des Integrals ergibt: %lf\n\n",F); printf("Wollen Sie ein neues Integral berechnen (y/n) ???: "); scanf("%c",&neu); }while((neu = 'y') || (neu = 'Y')); }
Ich wollte kein goto setzten, deshalb hab ich 2 while schleifen verwendet... aber irgendwie ging das in die Hose. Die Erste, für sich funktionier wunderbar, jedoch springt er bei der 2ten gleich wieder an Anfang der Main func, ohne eine Eingabe abzuwarten. Muss irgendetwas deppertes übersehen haben
nen Hint bitte
-
==
puffer leeren: int c; while ((c = getchar()) != EOF && c != '\n');
-
@ c.rackwitz : Danke für deine Antwort, aber leider versteh ich deine Antwort nicht so ganz. Warum genau muss ich meine Eingabe im Speicher zwischenspeichern, bzw. warum kann ich nicht scanf() benutzen ...
Danke
-
vergiss meine zeile von wegen "puffer leeren".
== bedeutet vergleich
= bedeutet zuweisung
pruefe das.
-
Ok, ich weiß jetzt wodran es lag und zwar war noch ein return, durch eine vorherige Eingabe im Speicher, wodurch das scanf abgebrochen wurde. Hab einfach noch ein fflush(stdin) reingesetzt und siehe es funzt.
Aber der Vergleichsoperator muss natürlich auch stimmen...Danke
-
el-duderado schrieb:
Ok, ich weiß jetzt wodran es lag und zwar war noch ein return, durch eine vorherige Eingabe im Speicher, wodurch das scanf abgebrochen wurde. Hab einfach noch ein fflush(stdin) reingesetzt und siehe es funzt.
Aber der Vergleichsoperator muss natürlich auch stimmen...Danke
falsch, falsch, falsch!
fflush(stdin) funzt nur bei MS compilern und ist KEIN ansi c. benutze es NIEMALS!
mit einem "return im speicher" hat das alles nichts zu tun.
dein vergleichsop stimmt NICHT! == ist vergleich, du aber hast = (zuweisung) verwendet.und jetzt erlange doch bitte schnellstmoeglich die erleuchtung.
-
Das war schon klar mit dem Vergleichsoperator, habe ich auch sofort geändert. Aber wenn du dir die Mühe machen möchtest und das Prog mal kompilierst, wirst du feststellen, dass er die scanf("%c",&neu); einfach übergeht. Das liegt meiner Meinung daran, dass ich im Speicher noch ein return hab und deshalb das scanf gleich weiter springt.
Ich könnte natürlich nochmal den Rückgabewert der scanf überprüfen, aber ich bin mir da eigentlich recht sicher.
-
Achso noch was, zum kompilieren benutze ich eigentlich immer dev-c++, da mir die Formatierung sowie die Fehlerüberprüfung darin aber garnicht gefällt, nehme ich dann immer visual c++. Evtl haste bezüglich des compilers ja noch einen Tipp
MfG
Micha
-
el-duderado schrieb:
Das liegt meiner Meinung daran, dass ich im Speicher noch ein return hab und deshalb das scanf gleich weiter springt.
deine meinung ist falsch, punkt. schlag dir den sch**** von wegen "return im speicher" aus dem kopf. klingt ja gerade zu als ob programmierung fuer dich etwas mit glauben und vermutungen zu tun haette.
das fuegst du bei den anderen variablendefinitionen hinzu:
int c;das setzt du unmittelbar vor die zeile mit dem scanf:
while ((c = getchar()) != EOF && c != '\n');machs einfach mal und tu nicht so als ob du wuesstest, was in deinem computer abgeht. das weiss dein computer naemlich besser als du
-
@rackwitz: Versteh deinen Standpunkt nicht - diese Vermutung ist durchaus legitm und dazu noch IMHO hier genau der Punkt!
Also was soll dann ein Spruch von wegen:c.rackwitz schrieb:
deine meinung ist falsch, punkt. schlag dir den sch**** von wegen "return im speicher" aus dem kopf. klingt ja gerade zu als ob programmierung fuer dich etwas mit glauben und vermutungen zu tun haette.
... dazu machst du durch deine "Lösung" (definitiv nicht failsave!) genau das: Du holst das return aus dem Eingabepuffer - zwar nur Nebeneffekt, aber immerhin:
c.rackwitz schrieb:
das setzt du unmittelbar vor die zeile mit dem scanf:
while ((c = getchar()) != EOF && c != '\n');machs einfach mal und tu nicht so als ob du wuesstest, was in deinem computer abgeht. das weiss dein computer naemlich besser als du
Sorry, aber in Verbindung damit verleihen solche Äusserungen deinen Postings eher Trollcharakter und kommt sehr arrogant rüber!
btw:
c.rackwitz schrieb:
und jetzt erlange doch bitte schnellstmoeglich die erleuchtung.
Wenn dich solche Fragen nerven, warum antwortest du drauf???
grüße
-
mir war nicht klar, dass du mit "return" einen zeilensprung meintest. in dem fall hast du recht, da koennte noch eins im puffer sein.
arroganz: du koenntest sehr wohl recht haben. ich werd mich aber dafuer nicht entschuldigen, weil ich mal davon ausgehen kann, dass hier keine mimosen mitlesen.
warum antworten: wenn ichs weiss, dann antworte ich, bevor sich ein paar noobs mit halbwissen gross fuehlen wollen.