C Programm um ALLE Ergebnisse auszugeben die "Bedingung" erfüllen

Warum schreibst du eigentlich nicht

x2 = -x1;

?

Hast recht das ist einfacher - werde ich noch ändern!

Mal abgesehen davon dass du da ziemlich viel mathematischen Blödsinn gemacht hast...
Wieso "4*0.1"?
Wieso (p*p-4*0.1)-p)?

Also vorgegeben hatte ich folgende Gleichung: x^2+p*x+q=0 und für q soll 0,1 eingesetzt werden.

Mit dieser Gleichung habe ich dank meines nicht vorhandenen "Programmier-skills" so gekämpft, dass ich die Gleichung erstmal nach x umgestellt habe - daraus resultieren die vorhandenen Gleichungen!

double zahl_unter_der_wurzel = p*p-4*0.1;
if (zahl_unter_der_wurzel < 0)
{
printf("Die Parabel mit den Werten p=%d, q=%d hat keine Nullstellen!\n", p, q);
}
else
....

Habe ich wie in meinem letzten Beitrag erwähnt bereits versucht funktioniert aber nicht!

Und es gibt noch ein weiteres Problem - die Ergebnisse stimmen zum Teil nicht! Habe noch eine Funktion eingebaut, die am Ende des Programmes die Ergebnisse in die Ausgangsgleichung (x^2+p*x+q) einsetzt und dann ausgibt ob das Ergebnis Null ist. Teilweise sind die Ergebnisse aber nicht 0 sondern bspw. 0.3*10^-9 und das wird wahrscheinlich als 0 angenommen - oder?
 
Zuletzt bearbeitet:
Deine Formel ist auch leider falsch.

Korrekt lautet sie (sollte auch in Mathe 1 vorkommen):
535a859b888af373ffbe3a8c2dd51c5a.png


D.h.: Y = -X trifft nicht immer zu. Es kann auch sowas rauskommen: X (bzw. X1) = 1,5, Y (bzw. X2) = 0,5
 
Zuletzt bearbeitet:
Das hast du jetzt aber dreist aus Wikipedia kopiert :D
 
Ich spende ja auch dafür :D
 
Ok jetzt geht es drunter und drüber ich verstehe gar nichts mehr...

Vielleicht ist das auch gar nicht die pq-Formel!? Wie gesagt vorgegeben ist x^2+p*x+q=0 und das habe ich nach x umgestellt - mehr nicht.

Und jetzt will ich für ein KOSTANTES q von 0,1 und ein VARIABLES p von 0 bis 2 in 0,1er Schritten ausgeben für welches x die Gleichung gültig ist.

Habe gerade noch zwei Fehler entdeckt deswegen hier nochmal die aktuelle Version:

#include <stdafx.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main( void ) {

double x1;
double x2;
float p;
float q = 0.1;
double Ergebnis_x1;
double Ergebnis_x2;

for (p = 0 ; p <= 2.1 ; p += 0.1) {

x1 = ((sqrt(p*p-4*q)-p)/2);
x2 = -((sqrt(p*p-4*q)+p)/2);

Ergebnis_x1 = x1*x1 + p*x1 + q;
Ergebnis_x2 = x2*x2 + p*x2 + q;

if (p < 0.7) { printf ("Fuer den Wert p=%f entsteht eine komplexe Zahl\n", p); }

else { printf ("p= %.2f\t x1= %g\t x2= %g\n", p, x1, x2); }

if (p < 0.7) { printf ("Kontrolle der Ergebnisse fuer x1= Komplexes Ergebnis\n");
printf ("Kontrolle der Ergebnisse fuer x2= Komplexes Ergebnis\n"); }

else { printf ("Kontrolle der Ergebnisse fuer x1= %f\n", Ergebnis_x1);
printf ("Kontrolle der Ergebnisse fuer x2= %f\n", Ergebnis_x2); }

}

system ("PAUSE");
return 0;

}
 
Zuletzt bearbeitet:
Mit dieser Gleichung habe ich dank meines nicht vorhandenen "Programmier-skills" so gekämpft, dass ich die Gleichung erstmal nach x umgestellt habe - daraus resultieren die vorhandenen Gleichungen!
Vielleicht ist das auch gar nicht die pq-Formel!? Wie gesagt vorgegeben ist x^2+p*x+q=0 und das habe ich nach x umgestellt - mehr nicht.
Doch das ist die pq formel und du hast beim Umstellen einen Fehler gemacht ODER beim abschreiben. Was du im Programm stehen hast ist nicht die Lösung von sasdensas wie sie auch auf Wikipedia steht.

Außerdem solltest du NIE NIE NIE irgendwo im Programm 0.1 schreiben nur weil das der Wert von q ist.
Schreib lieber oben wie du auch getan hast: double q = 0.1;
Du musst dann aber auch immer die Variable q verwenden und nicht 0.1 schreiben!

Es ist eine PQ-Formel und es gibt aufgrund des Quadrates 2 mögliche X-Werte.
Etwas genauer: Es gibt 0, 1 oder 2 reele Lösungen und immer genau 2 komplexe die im Falle deren Existenz mit den reelen identisch sind.
 
Doch das ist die pq formel und du hast beim Umstellen einen Fehler gemacht ODER beim abschreiben. Was du im Programm stehen hast ist nicht die Lösung von sasdensas wie sie auch auf Wikipedia steht.

Jap falsch abgetippt habe es gerade gemerkt und geändert!

Außerdem solltest du NIE NIE NIE irgendwo im Programm 0.1 schreiben nur weil das der Wert von q ist.

Auch gerade gemerkt und geändert ;)

Die zwei Probleme sind aber nach wie vor vorhanden:

Erstens: die if Abfrage mit p<0,7 ist unsauber
Zweitens: Die Ergebnisse müssten irgendwie als "Gleitkommazahl" ausgeben werden, damit nicht 3,69889*10^-9 zu 0 wird.

Ich Depp - Das zweite hat sich erledigt...
 
Zuletzt bearbeitet:
Poste mal deinen Code wie er zur Zeit ist, dann helf ich dir alles sauber und zur Abwechslung mathematisch korrekt zu machen!

Gruß
BlackMark
 
Also so sieht es momentan aus (hoffe das mit dem "Code" einfügen funktioniert):

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

	int main( void )	{

	double x1;
	double x2;
	float p;
	float q = 0.1;
	double Ergebnis_x1;
	double Ergebnis_x2;

		for (p = 0 ; p <= 2.1 ; p += 0.1)	{

			x1 = ((sqrt(p*p-4*q)-p)/2);
			x2 = -((sqrt(p*p-4*q)+p)/2);

			Ergebnis_x1 = x1*x1 + p*x1 + q;
			Ergebnis_x2 = x2*x2 + p*x2 + q;


				if (p < 0.7)	{	printf ("Fuer den Wert p=%f entsteht eine komplexe Zahl\n", p);		}

				else			{	printf ("\np= %.2f\t x1= %g\t x2= %g\n", p, x1, x2);					}

				if (p < 0.7)	{	printf ("Kontrolle der Ergebnisse fuer x1= Komplexes Ergebnis\n"); 
									printf ("Kontrolle der Ergebnisse fuer x2= Komplexes Ergebnis\n");	}

				else			{	printf ("Kontrolle der Ergebnisse fuer x1= %g\n", Ergebnis_x1); 
									printf ("Kontrolle der Ergebnisse fuer x2= %g\n", Ergebnis_x2);		} 

											}

 system ("PAUSE");
 return 0;

 }


...Naja leider alles bisschen verschoben - denke das verdanke ich wie immer dem Opera Browser :D
 
Also dann, räumen wir mal auf, aber vorher ein bisschen Mathe.
Du hast eine Quadratische Gleichung, die in der allgemeinen Form so aussieht: a*x² + b*x + c = 0
Wenn du die Gleichung durch a dividierst bekommst du:
x² + b/a*x + c/a = 0
Wenn du jetzt noch b/a und c/a als p und q definierst, dann hast du die Gleichung in der pq-Form.
p = b/a
q = c/a
x² + p*x + q = 0
Sobald deine Gleichung in dieser Form ist kannst du die pq-Formel anwenden, mit der du die beiden Lösungen dieser Gleichung bekommst.
Also: x1,2 = -p/2 +- sqrt( (p/2)² - q )
Das ist die Formel die du in deinem Programm haben musst, damit du auf die richtigen Lösungen kommst. Die Formel braucht man deshalb, weil man x nicht freistellen kann, wenn man x² und x in der selben Gleichung hat.

Aber nun zu deinem Code:
Code:
#include <stdafx.h>
Diese Zeile hab ich vorher übersehen, dazu muss noch etwas gesagt werden. stdafx.h ist kein Standardheader, sondern ein Header der vom Visual Studio erzeugt wird ( Stichwort: Precompiled Header ). Eigentlich brauchst du den nicht und kannst ihn weglassen, wenn du ihn aber einbindest, dann musst du das mit #include "stdafx.h" machen, weil es sich eben um einen Header handelt, der nicht vom Compiler bereitgestellt wird ( stdafx.h liegt im gleichen Ordner wie deine *.c Datei ).
Code:
double x1;
double x2;
Hier könnte man den Beistrichoperator verwenden. Der Beistrich in C ist kein Komma, sondern ein Trennoperator. Damit werden mehrere Parameter an eine Funktion übergeben, oder es werden mehrere Variablen vom gleichen Typ definiert. Das sieht dann so aus:
Code:
double x1, x2;
Das musst du nicht machen, deine Variante ist vollkommen in Ordnung, aber du solltest die andere Schreibweise auch kennen.
Code:
x1 = ( ( sqrt( p*p - 4*q ) - p ) / 2 );
x2 = -( ( sqrt( p*p - 4*q ) + p ) / 2 );
Die Formel stimmt nicht und du hast nicht ganz verstanden wie ich das mit meinem Division durch Null Beispiel gemeint habe. Du solltest auf keinen Fall in deinem Programm mathematisch undurchführbare Rechnungen haben. Eine Division durch Null kann unter umständen dein Programm zum Absturz bringen und muss deshalb vermieden werden. Das Gleiche gilt für negative Zahlen unter einer Wurzel. In meinem Beispiel habe ich vorher überprüft ob eine Division durch Null vorkommen wird und dann einen Fehler ausgegeben, die Rechnung aber nicht durchgeführt. Du machst es genau falsch herum, du führst die Rechnung aus und überprüfst nachher ob ein Fehler aufgetreten ist.
Die Zeile mit dem Ergebnis passt, aber danach kommt zwei mal die Überprüfung ob p kleiner als 0.7 ist. Wieso machst du das zwei mal?

Was du machen solltest ist für den Teil unter der Wurzel eine Variable anlegen und diese vorher überprüfen. Wenn diese Variable kleiner als Null ist, dann gibst du deine Fehlermeldung aus, wenn nicht, dann kannst du die PQ-Formel anwenden. Die Zeile mit der PQ-Formel darf aber nicht ausgeführt werden, wenn unter der Wurzel eine Zahl kleiner als Null ist!

Code:
system ("PAUSE");
Diese Zeile ist auch nicht sauber! Du solltest die system() Funktion vermeiden, weil sie nur auf Windows funktioniert und keine Standardfunktion ist. Besser ist, wenn du auf eine Eingabe wartest. Das geht zum Beispiel mit getchar(). Sieht dann so aus:
Code:
printf( "Press enter to exit . . . " );
getchar();

Den Code an sich werde ich dir nicht schreiben, du sollst ja schließlich etwas lernen, aber wenn du auf alles hörst was ich dir gesagt habe, solltest du am Ende ein sauberes und funktionierendes Programm haben. Falls du aber bei irgendetwas Hilfe brauchst, helfe ich gerne.

Gruß
BlackMark
 
Zuletzt bearbeitet:
Zunächstmal danke, dass du dir die Zeit nimmst so eine Ausführliche Antwort zu tippen! Du hast mir ohnehin schon ein ganzes Stück weiter geholfen aber deine aktuellste Antwort hat auch schon wieder diverse Fragen aufgeworfen. Aber eins nach dem anderen:

Die Formel braucht man deshalb, weil man x nicht freistellen kann, wenn man x² und x in der selben Gleichung hat.

Jetzt wo du es sagst ist es absolut logisch - habe mal wieder den TI rechnen lassen ohne das Gehirn einzuschalten...

...#include <stdafx.h>... Eigentlich brauchst du den nicht und kannst ihn weglassen...

Habe erst versucht den #include "stdafx.h" ganz wegzulassen mit folgendem Ergebniss:

error C1010: Unerwartetes Dateiende während der Suche nach dem vorkompilierten Header. Haben Sie möglicherweise vergessen, im Quellcode "#include "StdAfx.h"" einzufügen?

Jetzt sind wenigstens die < > durch " " ersetzt und es funktioniert wieder. Kann man scheinbar doch nicht ganz weglassen!?

Hier könnte man den Beistrichoperator verwenden.

Ist geändert und spart einige Zeilen ein. Werde ich mir in Zukunft angewöhnen. Wobei mir die andere Schreibweise besser gefällt weil es übersichtlicher ist aber die eingesparten Zeilen sind bestimmt wichtiger!?

Die Formel stimmt nicht und du hast nicht ganz verstanden wie ich das mit meinem Division durch Null Beispiel gemeint habe. Du solltest auf keinen Fall in deinem Programm mathematisch undurchführbare Rechnungen haben. Eine Division durch Null kann unter umständen dein Programm zum Absturz bringen und muss deshalb vermieden werden.

Klingt logisch und kann ich gut nachvollziehen aber das ist echt eine riesige Hyrde. Habe jetzt das Programm ziemlich stark umgestaltet und es funktioniert insgesamt nichtmehr so richtig - oder vielleicht auch erst jetzt richtig aber irgendwie komisch. :confused_alt:

Die Abfrage so einzufügen wie du es sagst (und wie es auch 100%ig ist) bekomme ich nicht hin :(

Die Zeile mit dem Ergebnis passt, aber danach kommt zwei mal die Überprüfung ob p kleiner als 0.7 ist. Wieso machst du das zwei mal?

Diese Abfrage war zweimal drinnen, weil sie einmal für den ersten Rechenschritt ausgeführt wurde - nämlich um die x-Werte zu erhalten und danch nocheinmal wenn dann die x-Werte in die "Überprüfungs-formel" eingesetzt wurden.

Diese Zeile ist auch nicht sauber! Du solltest die system() Funktion vermeiden, weil sie nur auf Windows funktioniert und keine Standardfunktion ist.

Da bist du nicht der erste der mich darauf hinweist - nur bist du der erste der auch eine alternative anbietet undzwar auch eine die funktioniert. Ist geändert und bestimmt jetzt sauberer als vorher!

Den Code an sich werde ich dir nicht schreiben, du sollst ja schließlich etwas lernen, aber wenn du auf alles hörst was ich dir gesagt habe, solltest du am Ende ein sauberes und funktionierendes Programm haben.

Klar ist auch besser nicht alles vorgekaut zu bekommen. Das Problem ist nur, dass seit meinen neuesten "Eingriffen" jetzt nurnoch komplexe Werte ausgegeben werden (und ich glaube das ist auch richtig so, denn das Ergebnis der Gleichung ist NIE wirklich Null).

Hier nochmal die aktuelle Version:


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

	int main( void )	{

	float p, q = 0.1;
	double x1, x2, Unter_Wurzel = (p/2)*(p/2) - q, Ergebnis_x1, Ergebnis_x2;
	
		for (p = 0 ; p <= 2.1 ; p += 0.1)	{

				x1 = -p/2 + sqrt(Unter_Wurzel);
				x2 = -p/2 - sqrt(Unter_Wurzel);

				Ergebnis_x1 = x1*x1 + p*x1 + q;
				Ergebnis_x2 = x2*x2 + p*x2 + q;
				
				printf ("\np= %.2f\t x1= %g\t x2= %g\n", p, x1, x2);

					if (p < 0.7)	{	printf ("Kontrolle der Ergebnisse fuer x1= Komplexes Ergebnis\n"); 
										printf ("Kontrolle der Ergebnisse fuer x2= Komplexes Ergebnis\n");		}

					else			{	printf ("Kontrolle der Ergebnisse fuer x1= %g\n", Ergebnis_x1); 
										printf ("Kontrolle der Ergebnisse fuer x2= %g\n", Ergebnis_x2);			} 
					
											}

	printf("\n\nBitte Enter druecken um das Programm zu verlassen");
	getchar();

 return 0;

 }
 
Zuletzt bearbeitet:
Pack mal
Code:
Unter_Wurzel = (p/2)*(p/2) - q
in die For-Schleife (vor x1 und x2).

Unter_Wurzel bleibt nämlich immer gleich und ändert sich nicht. In der Schleife wird p geändert und hat somit auch Auswirkung auf die Unter_Wurzel
 
Ok das bringt die ganze Aufgabe auch schon wieder ein Stück weiter ich verstehe aber beim besten Willen nicht warum, denn genau diese Zeile habe ich doch weiter oben bei "double" schonmal definiert!?
 
Die hast du definiert inkl. Berechnung, aber die hat da nichts zu Suchen. Oben soll sie nur definiert und ggfs. initialisiert werden. Die Variablen ändern sich aber in der For-Schleife. Du denkst vermutlich Funktional, aber das wäre nicht der richtige Weg.

Mach dich mal mit nem Debugger vertraut, dann kannst Du während der Laufzeit die Werte der Variablen anschauen; Schritt für Schritt, bzw. Zeile für Zeile.
 
Zunächstmal danke, dass du dir die Zeit nimmst so eine Ausführliche Antwort zu tippen!
Kein Problem, solange du Eigeninitiative an den Tag legst und nicht erwartest, dass andere deine Arbeit machen wird dir gerne geholfen, dazu sind Foren da.

Jetzt sind wenigstens die < > durch " " ersetzt und es funktioniert wieder. Kann man scheinbar doch nicht ganz weglassen!?
In deinen Projekteinstellungen sind vorkompilierte Header eingestellt und stdafx.h wird deshalb benötigt, weil dort eben die Header stehen sollten. Du hast deine Header aber in der *.c Datei stehen, weshalb stdafx.h für dich sinnlos ist. Wenn du es aber weglässt ohne die Einstellung zu ändern, dann gibt das natürlich einen Fehler. Wenn du ein neues Projekt erstellst, dann wirst du immer gefragt ob es vorkompilierte Header haben soll. Am besten ist, wenn du dort auf leeres Projekt klickst und keine vorkompilierten Header auswählst, dann kannst ( bzw. musst ) du das stdafx.h weglassen. Aber wenn du es verwendest, dann #include "stdafx.h" schreiben, aber das hast du ja schon.

Ist geändert und spart einige Zeilen ein. Werde ich mir in Zukunft angewöhnen. Wobei mir die andere Schreibweise besser gefällt weil es übersichtlicher ist aber die eingesparten Zeilen sind bestimmt wichtiger!?
In diesem Fall ist Lesbarkeit wichtiger! Zeilen sparen musst du nicht und macht auch keinen Sinn, am Ende kommt der gleiche Code raus. Für den Compiler macht es keinen Unterschied ob du das alles in einer Zeile schreibst oder nicht. Mach es so, wie man es am einfachsten lesen kann. Zum Beispiel:
Code:
float p, q = 0.1;
double x1, x2;
double Unter_Wurzel = (p/2)*(p/2) - q;
double Ergebnis_x1, Ergebnis_x2;

Die Abfrage so einzufügen wie du es sagst (und wie es auch 100%ig ist) bekomme ich nicht hin
Wieso nicht?
Code:
if( Unter_Wurzel < 0 )
{
    printf( "Fehler\n" );
}
else
{
    // Hier der Rest des Codes
    x1 = ...
}
Bedenke aber, dass eine Variable, sobald sie einen Wert hat, nicht von alleine geändert wird. Unter_Wurzel wird bei dir ganz am Anfang definiert, aber die Schleife verändert jedes mal p, das hat aber keinen Einfluss auf Unter_Wurzel. Was du also machst ist jedes mal den gleichen Wert für Unter_Wurzel verwenden. Dieser ist nur so nebenbei undefiniert! "float p, q = 0.1;" dort wird nur q ein Wert zugewiesen, p ist undefiniert. In der nächsten Zeile verwendest du aber p und q um Unter_Wurzel zu definieren, also kann man nicht wissen, was in Unter_Wurzel steht, weil man nicht weiß was in p steht und dein ganzes Programm könnte jederzeit abstürzen!

Code:
if (p < 0.7)
Lass das mal endlich weg und kontrolliere Unter_Wurzel und nicht p. Aber stell sicher, dass Unter_Wurzel bei jedem Schleifendurchlauf mit dem veränderten p definiert wird!

Edit: Da war wohl jemand etwas schneller...

Gruß
BlackMark
 
Zuletzt bearbeitet:
Die hast du definiert inkl. Berechnung, aber die hat da nichts zu Suchen. Oben soll sie nur definiert und ggfs. initialisiert werden. Die Variablen ändern sich aber in der For-Schleife.

Ist geändert - danke für die Erklärung warum das so war wie es war ;)

Du denkst vermutlich Funktional, aber das wäre nicht der richtige Weg.

Habe bisher ziemliche Schwierigkeiten in diese "Programmier-Denkweise" reinzukommen - ist halt völliges Neuland für mich und daher sehr ungewohnt. Vor allem fällt es mir schwer nachzuvollziehen wie die Schleifen "ineinandergreifen" und wie an sich die Abläufe funktionieren. Aber es wird langsam besser ;)

In diesem Fall ist Lesbarkeit wichtiger! Zeilen sparen musst du nicht und macht auch keinen Sinn, am Ende kommt der gleiche Code raus. Für den Compiler macht es keinen Unterschied ob du das alles in einer Zeile schreibst oder nicht. Mach es so, wie man es am einfachsten lesen kann.

Ok habe es jetzt auch wieder etwas geändert - leicht zusammengefasst aber noch übersichtlich. Vorher das hat mir nicht gefallen aber dachte es wäre gut Zeilen zu sparen wegen der Geschwindigkeit des Programmes oder so (was in diesem Fall hier eh keine Rolle spielt aber später vielleicht).

Die Abfrage so einzufügen wie du es sagst (und wie es auch 100%ig ist) bekomme ich nicht hin


Das funktioniert nicht so wie du es geschrieben hast (oder ich bin wieder zu unfähig es richtig umzusetzen) aber die imaginären Werte werden immernoch ausgerechnet und ausgegeben...

Nachtrag:
Das hier ist der aktuelle Stand (hat sich nochmal einiges geändert)

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main( void ) {

float p, q = 0.1;
double x1, x2;
double Unter_Wurzel, Ergebnis_x1, Ergebnis_x2;

if (Unter_Wurzel <= 0) printf ("Fatal error!!!!111elf");

else { for (p = 0 ; p <= 2.1 ; p += 0.1) {

Unter_Wurzel = (p/2)*(p/2) - q;

x1 = -p/2 + sqrt(Unter_Wurzel);
x2 = -p/2 - sqrt(Unter_Wurzel);

Ergebnis_x1 = x1*x1 + p*x1 + q;
Ergebnis_x2 = x2*x2 + p*x2 + q;

printf ("\n\nWert fuer p= %.2f\tErgebnis x1= %g\tErgebnis x2= %g\n", p, x1, x2);

if (Ergebnis_x1 == 0 && Ergebnis_x2 == 0) { printf ("Probe fuer x1= %g\tProbe fuer x2= %g\n", Ergebnis_x1, Ergebnis_x2); }
if (Ergebnis_x1 == 0 && Ergebnis_x2 != 0) { printf ("Probe fuer x1= %g\tBedingung fuer x2 nicht erfuellt\n", Ergebnis_x1); }
if (Ergebnis_x1 != 0 && Ergebnis_x2 == 0) { printf ("Bedingung fuer x1 nicht erfuellt, da x1= %g\tProbe fuer x2= %g\n",Ergebnis_x1, Ergebnis_x2); }
if (Ergebnis_x1 != 0 && Ergebnis_x2 != 0) { printf ("Gleichungsbedingungen nicht erfuellt\n", Ergebnis_x2); }

}}

printf("\n\nBitte Enter druecken um das Programm zu verlassen");
getchar();

return 0;

}
 
Zuletzt bearbeitet:
Habe bisher ziemliche Schwierigkeiten in diese "Programmier-Denkweise" reinzukommen - ist halt völliges Neuland für mich und daher sehr ungewohnt. Vor allem fällt es mir schwer nachzuvollziehen wie die Schleifen "ineinandergreifen" und wie an sich die Abläufe funktionieren.
Dann wird es Zeit dich mit deinem neuen besten Freund vertraut zu machen: dem Debugger! Ein Debugger erlaubt es dir dein Programm schrittweise durchzuführen. Du kannst einen sogenannten Breakpoint setzen und dieser tut genau das, was sein Name andeutet, er stoppt das Programm an dieser Stelle. Um im Visual Studio einen Breakpoint zu setzen klickst du einfach ganz links auf den Rand der Zeile, dann kommt ein roter Punkt, der dein Breakpoint ist. Wenn du jetzt das Programm im Debug Mode startest, dann läuft das Programm bis zu diesem Punkt und stoppt dann. Wenn das Programm gestoppt ist, dann kannst du mit der Maus über eine Variable fahren und es wird dir angezeigt welchen Wert sie hat. Es gibt dann noch die Möglichkeit, dass du das Programm einfach weiterlaufen lässt ( F5 ) oder, dass du den nächsten Befehl ausführst, also einfach eine Zeile weiter gehst ( F10 ), das nennt sich "stepping", weil du schrittweise durch den Code gehst. Wenn da eine Funktion ist, dann kannst du auch mit ( F11 ) in diese Funktion springen, dann siehst du den Code dieser Funktion ( bei printf oder so etwas siehst du maximal den Assemblercode, weil der Code von printf nicht dem Compiler beiliegt ), also F11 bringt dir nur etwas, wenn du in deine eigenen Funktionen springen willst. Das nennt sich nebenbei Step-Over ( F10 ), also über die Funktion gehen oder Step-Into ( F11 ), also in die Funktion gehen. Wenn du einen Breakpoint auf die erste Zeile deines Programms setzt, dann kannst du mit F10 ganz einfach durchgehen und verfolgen was bei jedem Schritt passiert und welchen Wert die entsprechenden Variablen haben. Der Debugger ist wirklich der beste Freund des Programmierers.

dachte es wäre gut Zeilen zu sparen wegen der Geschwindigkeit des Programmes
Es ist wichtig schönen, sauberen und effizienten Code zu schreiben, aber es gibt Dinge, die der Compiler immer gleich umsetzt, egal wie du es schreibst. Es ist vollkommen egal, ob du die Variablen in eine Zeile schreibst oder in mehrere, am Ende macht der Compiler den gleichen Code daraus. Es ist jedoch nicht egal, ob du zwei mal eine "if( p < 0.7 )" hast, denn das fasst der Compiler nicht zusammen.

Das funktioniert nicht so wie du es geschrieben hast
Doch doch, das funktioniert schon.

Das hier ist der aktuelle Stand
Warum schon wieder ohne CODE-Tags? Verwende bitte CODE-Tags, auch wenn die Einrückung etwas übertrieben ist.

Code:
double Unter_Wurzel, Ergebnis_x1, Ergebnis_x2;

if (Unter_Wurzel <= 0) printf ("Fatal error!!!!111elf");
Welchen Wert hat Unter_Wurzel denn hier? Richtig, gar keinen! Du darfst nicht eine Variable, der noch kein Wert zugewiesen wurde, vergleichen! In Unter_Wurzel steht irgendetwas, das ist vollkommen zufällig was darin steht, es ist halt das, was vorher an dieser Stelle im Speicher war, das kann kleiner-gleich Null sein, aber auch nicht. Undefiniertes Verhalten und sehr sehr schlechte Programmierung! Merk dir das bitte: Auf keinen Fall mit einer Variable arbeiten, die noch keinen Wert hat!

Code:
Unter_Wurzel = (p/2)*(p/2) - q;

x1 = -p/2 + sqrt(Unter_Wurzel);
x2 = -p/2 - sqrt(Unter_Wurzel);
Das steht jetzt in der Schleife, sehr gut! Du berechnest also das was unter der Wurzel steht und weist es der Variable Unter_Wurzel zu, danach berechnest du x1 und x2 und weist es den entsprechenden Variablen zu. Wo aber, wird überprüft, ob Unter_Wurzel kleiner als Null ist? ( kleiner als Null, nicht kleiner gleich Null! Die Wurzel aus Null ist Null und führt zu keinem Fehler! )
Was du tun musst ist ganz einfach. Nachdem du Unter_Wurzel berechnet hast überprüfst du es, ob es kleiner als Null ist! Das geht mit "if( Unter_Wurzel < 0 )". Ich glaube du hast noch nicht ganz verstanden wie if Funktioniert, also hier eine Erklärung:
Code:
if( Bedingung )
{
    // Wenn Bedingung wahr ist ( also größer gleich 1 ist ), dann springen wir in diesen Codeblock ( Ein Codeblock ist alles zwischen {}
}
else
{
    // Wenn Bedingung falsch ist ( also gleich 0 ist ), dann springen wir in diesen Codeblock
}
Wahr und falsch funktionieren in C folgendermaßen: Alle Zahlen größer gleich 1 sind wahr und Null ist falsch. Wenn du also "if( 7 )" schreibst, dann ist das wahr und du springst in den ersten Block, wenn du "if( 0 )" schreibst, dann ist das falsch und du springst in den zweiten Block. Dann gibt es noch Vergleichsoperatoren, wie zum Beispiel "==" oder "<=" oder "<" und so weiter. Diese Operatoren nehmen zwei Werte und vergleichen sie und wenn das Ergebnis wahr ist, dann kommt eine 1 raus und wenn das Ergebnis falsch ist, dann kommt eine 0 heraus. Zum Beispiel "if( 7 == 5 )", da wird der Vergleich durchgeführt, der offensichtlich falsch ist und dann steht da "if( 0 )" und dann springt man in den zweiten Block, also in den else Block. Wenn ( if ) etwas wahr ist, dann mach das, sonst ( else ) mach etwas anderes.
Genau das ist, was du brauchst. Wenn ( if ) p kleiner als Null ist, dann gib einen Fehler aus, sonst ( else ) führe die Berechnung fort.

Das bekommst du doch hin, oder?

Gruß
BlackMark
 
Das mit den roten Punkten (Debugger) funktioniert gut! So konnte ich jetzt feststellen, dass das q immer 0,1 bleibt - man hat sozusagen einen Beweis und muss sich nicht blind verlassen.

Die Funktionen von F5, F10 und F11 sind auf meinem Merkzettel aufgenommen (wir dürfen eine DinA4 Seite beidseitig beschrieben mit in die Klausur nehmen - das wird dann dieser "Merkzettel" werden. Mal sehen was da so draufsteht wenn es dann ernst wird).

Du hast nur das zitiert:
Das funktioniert nicht so wie du es geschrieben hast
aber den wichtigeren Teil weggelassen:
(oder ich bin wieder zu unfähig es richtig umzusetzen)
;)

Denn daran lag es - die if-Abfrage war an der falschen Stelle!

Merk dir das bitte: Auf keinen Fall mit einer Variable arbeiten, die noch keinen Wert hat!

Jap stimmt darauf muss ich achten kommt ja immer drauf an was vorher an diesem Speicherplatz war. So hätte der Befehl sogar funktionieren können wenn eben vorher die richtige Zahl dort abgelegt worden wäre!

Warum schon wieder ohne CODE-Tags? Verwende bitte CODE-Tags, auch wenn die Einrückung etwas übertrieben ist.

Das ging leider nachträglich nichtmehr. Hatte schon auf antworten gedrückt und in der "Bearbeiten-Funktion" kann man keine Code-Tags mehr einfügen. Aber für die Zukunft weiss ich wie sie heissen und tippe sie im Falle des Falles einfach dazu!

Ich glaube du hast noch nicht ganz verstanden wie if Funktioniert,...

Doch, doch die Funktoinsweise habe ich schon verstanden aber ich stand total auf der Leitung, deshalb lag die if-Abfrage wie schon gesagt die ganze Zeit an der völlig falschen Stelle.

Und so sieht es jetzt aus und dürfte damit auch (eigentlich) endlich geschafft sein:

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

	int main( void )	{

	float p, q = 0.1;
	double x1, x2;
	double Unter_Wurzel, Ergebnis_x1, Ergebnis_x2;
	
	
	
		for (p = 0 ; p <= 2.1 ; p += 0.1) {

				Unter_Wurzel = (p/2)*(p/2) - q;
			
				if (Unter_Wurzel < 0) { printf ("Wert unter Wurzel kleiner 0 - Fehler!\n\n"); }

				else {

				x1 = -p/2 + sqrt(Unter_Wurzel);
				x2 = -p/2 - sqrt(Unter_Wurzel);

				Ergebnis_x1 = x1*x1 + p*x1 + q;
				Ergebnis_x2 = x2*x2 + p*x2 + q;
				
				printf ("\n\nWert fuer p= %.2f\tErgebnis x1= %g\tErgebnis x2= %g\n", p, x1, x2);
				
				if (Ergebnis_x1 == 0 && Ergebnis_x2 == 0) { printf ("Probe fuer x1= %g\tProbe fuer x2= %g\n", Ergebnis_x1, Ergebnis_x2); }
				if (Ergebnis_x1 == 0 && Ergebnis_x2 != 0) { printf ("Probe fuer x1= %g\tBedingung fuer x2 nicht erfuellt\n", Ergebnis_x1); }
				if (Ergebnis_x1 != 0 && Ergebnis_x2 == 0) { printf ("Bedingung fuer x1 nicht erfuellt, da x1= %g\tProbe fuer x2= %g\n",Ergebnis_x1, Ergebnis_x2); }
				if (Ergebnis_x1 != 0 && Ergebnis_x2 != 0) { printf ("Gleichungsbedingungen nicht erfuellt\n", Ergebnis_x2); }
					
	}}

	printf("\n\nBitte Enter druecken um das Programm zu verlassen");
	getchar();

 return 0;

 }
 
Zuletzt bearbeitet:
Zurück
Oben