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

12th Monkey

Cadet 3rd Year
Registriert
Feb. 2010
Beiträge
45
Ahoi CB'ler;

ich beschäftige mich seit ganz kurzer Zeit mit C bzw. C++ und stehe gerade vor einem Problem bei dem ihr mir vielleicht helfen könnt...

Undzwar möchte ich ein Programm schreiben, das mir alle Ergebnisse ausgibt, die in Frage kommen damit eine Gleichung "Null" ergibt.

Es geht um diese Gleichung: x*x+p*x+q=0 (PQ-Formel)
Für q wird der "feste Wert" 0,1 eingesetzt
Für p werden nacheinander in 0,1er Schritten die Zahlen von 0 bis 2 eingesetzt

und ich möchte im Endeffekt die in Frage kommenden Werte für x ausgeben.

Bisher sieht mein Programm so aus:
...Bitte nicht lachen ich bin echt noch nicht lange dabei ;)

#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"

int main(array<System::String ^> ^args) {

double x;
float p;

for (p = -0,1 ; p <= 2,1 ; p += 0,1) {

x*x + p*x + 0,1 == 0;

printf ("%f\n", x); }

system ("PAUSE");
return 0;

}


Momentan spammt das Programm die 0. Habe schon diverse andere Versuche gestartet aber dieser hier ist bisher der beste...

Grüße
12th Monkey
 
Zuletzt bearbeitet: (Rechtschreibung)
Zuletzt bearbeitet:
So einen Versuch gab es auch schonmal - das sah dann so aus:

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

int main(array<System::String ^> ^args) {

double x;
double y;
float p;

for (p = -0,1 ; p <= 2,1 ; p += 0,1) {

x = ((sqrt(p*p-4*0,1)-p)/2);
y = -((sqrt(p*p-4*0,1)-p)/2);

printf ("%g\n%g\n", x, y); }

system ("PAUSE");
return 0;

}

Da kommt aber dann die Fehlermeldung "Error C2661" und bisher habe ich nicht rausgefunden was das Problem ist.

Sorry für den falschen Threadtitel - Ich nehme an das ist dann C++ oder? Habe noch nicht so richtig begriffen welche Sprache ich hier überhaupt anwende deswegen habe ich am Anfang auch geschrieben C bzw. C++
 
Zuletzt bearbeitet: (Ergänzung)
ich beschäftige mich seit ganz kurzer Zeit mit C bzw. C++
Was denn jetzt? C oder C++? Das sind zwei verschiedene Sprachen!

Bist du sicher, dass du die Gleichung durch Brute-Force lösen willst? Du kannst auch einfach die PQ-Formel verwenden: x1,2 = -p/2 +- sqrt( (p/2)² - q )
Damit bekommst du die richtigen Lösungen ohne dass du alle Zahlen durchprobieren musst.

Nun zu deinem Programm, das offensichtlich C und nicht C++ sein soll!
Code:
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
Du hast die falschen Zeichen verwendet, mit "" inkludierst du deine eigenen Header bzw. Header die nicht vom Compiler bereitgestellt werden, du musst <> verwenden.
Code:
#include <stdafx.h>
#include <stdio.h>
#include <stdlib.h>

Code:
int main(array<System::String ^> ^args)
Das ist nicht C, sondern C++/CLI, also vergiss das mal ganz schnell wieder.
Wenn du keine Parameter brauchst, dann solltest du das so schreiben:
Code:
int main() // alternativ: int main( void )
Wenn du die Parameter haben willst, dann schreibst du das so:
Code:
int main( int argc, char *argv[] ) // alternativ: int main( int argc, char **argv )
Code:
for (p = -0,1 ; p <= 2,1 ; p += 0,1)
Merk dir, dass für einen PC das Komma nicht der Beistrich ist, sondern der Punkt. Der Beistrich hat in C eine andere Bedeutung!
Sollte also so lauten:
Code:
for( p = -0.1; p <= 2.1; p += 0.1 )
Code:
x*x + p*x + 0,1 == 0;
Du hast wieder das falsche Komma Zeichen verwendet, müsste also 0.1 heißen.
Der == Operator vergleicht zwei Werte und liefert dir wahr ( 1 ) oder falsch ( 0 ) zurück. In dieser Zeile vergleichst du also ob die Formel gleich null ist, aber es passiert nichts. Zum einen hat x keinen Wert, weil du nirgens x einen Wert zuweist und zum anderen steht nach dem Vergleich in dieser Zeile entweder "1;" oder "0;", was beides keine Auswirkung auf dein Programm hat.

Danach gibst du x aus, aber x hat nie einen Wert bekommen, also wird einfach das ausgegeben was eben vorher an dieser Speicheradresse war, das kann irgendetwas sein und führt deshalb zu undefiniertem Verhalten.

Wenn du vergleichen willst ob etwas wahr oder falsch ist, dann nimmt man dazu if, also zum Beispiel:
Code:
if( x*x + p*x + 0.1 == 0 )
{
     printf( "%f\n", x );
}

Du musst aber vorher sicherstellen, dass x und p jeweils die richtigen Werte haben und nicht undefiniert sind!

Gruß
BlackMark
 
y = -((sqrt(p*p-4*0,1)-p)/2);

Meckert vermutlich wegen dem Minus. Probier stattdessen *-1

EDIT: stimmt, das Komma ist falsch :D. Wäre ein Parametertrenner in dem Fall
 
Zuletzt bearbeitet:
Was denn jetzt? C oder C++? Das sind zwei verschiedene Sprachen!

Das ist mir klar - die Hintergrundgeschichte dazu ist, dass unser Prof eigentlich C mit uns machen wollte aber in den Übungen ständig mit C++ Befehlen und C++ Entwicklungsumgebung gearbeitet wird...

Bist du sicher, dass du die Gleichung durch Brute-Force lösen willst?

Ähhm, ich glaube nicht - keine Ahnung ehrlich gesagt :mussweg:

Das mit " " bzw < > habe ich beides schon ausprobiert und ich glaube, dass es das selbe Ergebnis liefert (aber sicher bin ich da nicht - gab halt nur bisher nie Probleme). Aber werde mir dann wohl < > angewöhnen!

int main(array<System::String ^> ^args) - Das ist nicht C, sondern C++/CLI, also vergiss das mal ganz schnell wieder. Wenn du keine Parameter brauchst, dann solltest du das so schreiben:

Was diese Zeilen bedeuten hat unser Prof nie erklärt aber auf Nachfrage meinte er es ist beides ok!?

Merk dir, dass für einen PC das Komma nicht der Beistrich ist, sondern der Punkt. Der Beistrich hat in C eine andere Bedeutung!

Genau damit hatte ich in einer vorherigen Aufgabe Probleme, denn wenn man den Befehl 2.8.e-6 oder so anwendet gibt es eine Fehlermeldung wenn man aber 2,8.e-6 schreibt funktioniert es.

Der == Operator vergleicht zwei Werte und liefert dir wahr ( 1 ) oder falsch ( 0 ) zurück.

Oh ok das kann dann ja nicht funktionieren - es soll ja nichts verglichen werden sondern Werte ausgegeben werden die gewährleisten, dass die Gleichung stimmt.

P.S.: Habe gerade mal ausprobiert die " " in < > zu ändern und die Kommas durch Punkte ersetzt. Das Programm sieht jetzt schon besser aus! Keine Fehlermeldung mehr und einige Ergebnisse - ob die aber richtig sind ist die nächste Frage :D
 
Zuletzt bearbeitet:
Das ist mir klar - die Hintergrundgeschichte dazu ist, dass unser Prof eigentlich C mit uns machen wollte aber ständig mit C++ Befehlen und C++ Benutzeroberfläche arbeitet...
Traurig, traurig. Wenn die Lehrperson schon unfähig ist, wie sollen dann die Schüler jemals etwas richtig lernen.

Ähhm, ich glaube nicht - keine Ahnung ehrlich gesagt
Dann nimm die PQ-Formel her und versuch es damit zu lösen. Wenn du das geschafft hast kannst du immernoch eine Brute-Force Methode schreiben.

Das mit " " bzw < > habe ich beides schon ausprobiert und ich glaube, dass es das selbe Ergebnis liefert (aber sicher bin ich da nicht - gab halt nur bisher nie Probleme). Aber werde mir dann wohl < > angewöhnen!
Es gibt einige Dinge bei der Programmierung, die auch funktionieren, wenn man etwas anders macht als es eigentlich gedacht ist, aber das nennt man dann unsaubere Programmierung. Dass etwas zufällig funktioniert heißt noch lange nicht, dass man es so machen sollte. Also für alle Header der vom Compiler bereitgestellt werden solltest du <> verwenden.

Was diese Zeilen bedeuten hat unser Prof nie erklärt aber auf Nachfrage meinte er es ist beides ok...
Es ist nicht "beides ok". Das ist noch unsaubere Programmierung als die Headerklammern. Der einzige Grund warum dir das nicht um die Ohren fliegt ist, dass du das Ganze mit dem Microsoft C++ Compiler kompilierst und der eben C++/CLI kann. Dein Code funktioniert aber nicht, wenn du ihn mit einem richtigen C Compiler kompilierst und da du ja eigentlich C lernen solltest, vergiss das und verwende die richtige C main Funktion.
Genau damit hatte ich in einer vorherigen Aufgabe Probleme, denn wenn man den Befehl 2.8.e-6 oder so anwendet gibt es eine Fehlermeldung wenn man aber 2,8.e-6 schreibt funktioniert es.
Wenn du die Notation mit e wirklich benötigst ( wieso? ), dann geht das so: float fValue = 2.8e-6f; // Das f am Ende steht dafür, dass es eine float ist, bei double lässt man das f weg.

Edit:
Keine Fehlermeldung mehr und einige Ergebnisse - ob die aber richtig sind ist die nächste Frage
Das kannst du ja ganz einfach überprüfen. Wenn du die Werte in deine Gleichung einsetzt und es kommt 0 heraus, dann stimmen sie.

Gruß
BlackMark
 
Zuletzt bearbeitet:
Traurig, traurig. Wenn die Lehrperson schon unfähig ist, wie sollen dann die Schüler jemals etwas richtig lernen.

Es macht eigentlich ganz und garnicht den Anschein als ob er unfähig wäre. Er selbst hat es schon ziemlich raus aber er ist nicht unbedingt "ein Mann der klaren Worte" und so ist es ein wenig chaotisch und wie gesagt kommen halt dann solche Geschichten bei heraus wie "das ist beides ok".

Also für alle Header der vom Compiler bereitgestellt werden solltest du <> verwenden.

Werde ich mir angwöhnen!

Der einzige Grund warum dir das nicht um die Ohren fliegt ist, dass du das Ganze mit dem Microsoft C++ Compiler kompilierst und der eben C++/CLI kann. Dein Code funktioniert aber nicht, wenn du ihn mit einem richtigen C Compiler kompilierst und da du ja eigentlich C lernen solltest, vergiss das und verwende die richtige C main Funktion.

Ahh ok jetzt habe ich wenigstens mal eine Erklärung dafür! Werde mir dann auch den C Header angewöhnen und wenn mich nochmal jemand fragen sollte werde ich sagen, dass ich C programmiere und nicht mehr "C bzw. C++". :D

Wenn du die Notation mit e wirklich benötigst ( wieso? )...

Die Schreibweise mit .e-9 hat mir besser gefallen als diese Geschichte mit pow() das ist der einzige Grund dafür. Aber deine Schreibweise (2.8e-6f) gefällt mir sowieso besser - dann nehme ich das auch mal auf meinen Merkzettel auf!

P.S.: Also ich habe das Programm nochmal ein wenig umgeschrieben, damit ich zu dem jeweiligen Wert für "p" auch direkt angezeigt bekomme was für "x" und was für "y" herauskommt (die Werte stimmen übrigens habe es mit dem Taschenrechner ausprobiert). Das einzige Problem was ich jetzt noch habe ist, dass die "x" und "y" Werte für "b" bis 0,6 aus "Hyroglyphen" bestehen...

Kann das Programm vielleicht jemand ansehen und sagen warum das so ist (glaube das liegt daran, dass double nicht mehr ausreicht um die Zahl darzustellen aber bin nicht sicher).

So sieht es jetzt aus:

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

int main( void ) {

double x;
double y;
float p;

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

x = ((sqrt(p*p-4*0.1)-p)/2);
y = -((sqrt(p*p-4*0.1)-p)/2);

printf ("%f %g %g\n", p, x, y); }

system ("PAUSE");
return 0;
}
 
Zuletzt bearbeitet:
Es macht eigentlich ganz und garnicht den Anschein als ob er unfähig wäre. Er selbst hat es schon ziemlich raus aber er ist nicht unbedingt "ein Mann der klaren Worte" und so ist es ein wenig chaotisch und wie gesagt kommen halt dann solche Geschichten bei heraus wie "das ist beides ok".
Das macht ihn leider als Lehrer unfähig. Theoretisches Beispiel: "Ich habe einen Deutschlehrer, der ist wirklich sehr intelligent und weiß sehr viel, aber während des Deutschunterrichts fängt er immer an ein paar Sätze auf Englisch zu sagen und wenn man ihn fragt warum, dann sagt er 'Es ist beides ok'." Ein Lehrer der den falschen Stoff unterrichtet ist leider kein guter Lehrer.

Aber deine Schreibweise (2.8e-6f) gefällt mir sowieso besser
Das ist nicht "meine" Schreibweise, sondern das ist die einizige richtige Schreibweise! ( Du kannst das e auch groß schreiben (2.8E-6f), aber vor dem e kommt kein Punkt und auch kein Beistrich. )

Ansonsten wünsche ich dir viel Spaß beim C lernen!

Gruß
BlackMark
 
Kann das Programm vielleicht jemand ansehen und sagen warum das so ist (glaube das liegt daran, dass double nicht mehr ausreicht um die Zahl darzustellen aber bin nicht sicher).
Nimm mal ein Blatt Papier und schreibe die Gleichung auf und setze das entsprechende p ein. Vielleicht fällt dir dann auf was nicht stimmt.

Gruß
BlackMark
 
Für den Einstieg mit C kann ich dieses Buch empfehlen: http://www.amazon.de/C-Programmieren...3426583&sr=8-1

Genau das hat unser Prof auch empfohlen denke ich werde es mir morgen mal in der Bib ausleihen - dachte zwar ich würde das auch mit Youtube und Wikipedia hinbekommen aber das scheint doch etwas zu chaotisch zu werden... ;)

Ansonsten wünsche ich dir viel Spaß beim C lernen!

Danke dir! Bisher ist es schon nicht schlecht und dennoch hoffe ich, dass wir bald mal was anderes als diesen "Zahlensalat" à la "sortiere diese Zahlen" oder "zeige das diese Zahlen Vielfache von..." zu Gesicht bekommen.

Mein Problem mit den "Hyroglyphen" hat sich auch schon erledigt habe es selbst gefunden - es handelt sich bei diesen Zahlen um komplexe Zahlen (#IND und #QNAN)
 
dass wir bald mal was anderes als diesen "Zahlensalat" à la "sortiere diese Zahlen" oder "zeige das diese Zahlen Vielfache von..." zu Gesicht bekommen.
So lernt man eben die Grundlagen, da werden noch viele solche Beispiele auf dich zukommen, als nächstes dann wahrscheinlich mit Buchstaben und nicht mehr mit Zahlen. ( "Zähle wie oft jeder Buchstabe in diesem Satz vorkommt", "Gib dieses Wort rückwärts aus", ... )

es handelt sich bei diesen Zahlen um komplexe Zahlen
Richtig, du hast eine negative Zahl unter der Wurzel, deshalb bekommst du eine Komplexe-Zahl.

Gruß
BlackMark
 
Und hier ist schon das nächste Problem... Jetzt wollte ich versuchen die Zahlen die "komplex" herauskommen so ausgeben zu lassen, dass dort steht "komplexe Zahl" und nicht mehr #IND oder #QNAN.

Das Programm dazu sieht so aus:

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

int main( void ) {

double x;
double y;
float p;

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

x = ((sqrt(p*p-4*0.1)-p)/2);
y = -((sqrt(p*p-4*0.1)-p)/2);


if (x == #IND) { printf ("komplexe Zahl"); }
if (y == #QNAN) { printf ("komplexe Zahl"); }

else printf ("%f %g %g\n", p, x, y); }

system ("PAUSE");
return 0;

}

Die Ausgabe beschert mir eine ganze Reihe an Fehlermeldungen die fast ausschließlich deswegen zu Stande kommen weil angeblich Klammern oder Semikolons (keine Ahnung wie die Mehrzahl davon heisst) fehlen. Aber egal wie ich die Satzzeichen ändere an den Fehlermeldungen ändert sich nichts!?
 
Ich dachte du hättest dich über #IND und #QNAN informiert? Das sind Fehlermeldungen, du kannst nicht einfach die Zahl mit der Fehlermeldung vergleichen. In C bedeutet #, dass du dem Präprozessor etwas mitteilen willst, zum Beispiel sagst du ihm, welche Header gebraucht werden ( #include <> ) und es gibt noch einige andere Befehle für den Präprozessor, die alle mit # anfangen. Wenn du also deinen Code so schreibst, dann versucht der Präprozessor den Befehl #IND und #QNAN auszuführen, was aber kein gültiger Befehl ist.
Du solltest generell vermeiden, dass es überhaupt zu #IND und #QNAN kommt, also vorher überprüfen ob eine Rechnung durchgeführt werden kann. Angenommen du schreibst etwas wo eine Division durch eine Variable ist, dann machst du das in etwa so:
Code:
int x = rand() % 10; // rand() gibt dir eine zufällige Zahl und mit % 10 bekommst du Zahlen von 0 bis 9. Die sind aber nicht gleichmäßig verteilt und ohne srand() vorher aufzurufen sind das immer die selben Zahlen
float fErgebnis;

if( x == 0 )
{
    printf( "Division durch 0!\n" );
}
else
{
    fErgebnis = 100.0f / x;
    printf( "Ergebnis: %f\n", fErgebnis );
}

Dadurch, dass x abgefangen wird, sobald es null ist, kommt es nicht zu einer Division durch 0. Du musst jetzt nur das gleiche Prinzip auf deine Aufgabe anwenden.

Gruß
BlackMark
 
Ja das #IND und #QNAN Fehlermeldungen sind habe ich schon verstanden aber ich dachte, dass man einfach im Falle der entstehenden Fehlermeldung einen zugehörigen printf Befehl "auslösen" könnte.
Aber habe es dank deiner Ausführung jetzt verstanden - die Raute macht einen Strich durch die Rechnung.

Das Prinzip, das du mit dem rand() Befehl erklärst kenne ich schon (nur das rand() noch nicht). Wie gesagt war meine Idee eben, dass man im Falle des entstandenen Fehlers eine Fehlermedlung ausgibt aber du hast schon recht - den Fehler gleich von vornherein zu vermeiden ist sauberer ;)


Nachtrag:

Also ich bin jetzt FAST zu frieden mit dem Programm - so sieht es aus:

#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;

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

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


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); }


system ("PAUSE");
return 0;

}

Was mir noch gar nicht gefällt sind die "festen" Werte für p (damit meine ich if (p<0.7)). Eine andere Möglichkeit konnte ich bisher aber nicht finden. Getestet wurde:

if ( x1 <= 0 || x2 <= 0)
if ( x1 == 0 || x2 == 0)
für (sqrt(p*p-4*0.1) die Variable "Wurzel" eingesetzt und mit if (Wurzel <= 0) abgefragt
für (p*p-4*0.1) die Variable Unter_Wurzel eingesetzt und mit if (Unter_Wurzel <= 0) abgefragt

und noch ein paar andere Versionen die eh nicht funktionieren konnten sozusagen als Verzweiflungsversuche ;-)

Habt ihr noch eine Idee wie man das machen könnte?
 
Zuletzt bearbeitet: (Rechtschreibung)
Aber mit welchem Befehl kann man eine Zahl unter der Wurzel abfragen?
Ohne deine Mathefehler zu korrigieren geht das folgendermaßen: Du machst dir eine neue Variable.
Code:
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
 ....

Mal abgesehen davon dass du da ziemlich viel mathematischen Blödsinn gemacht hast...
Wieso "4*0.1"?
Wieso (p*p-4*0.1)-p)?
 
Zuletzt bearbeitet:
Warum schreibst du eigentlich nicht

x2 = -x1;

?
 
Zurück
Oben