Es geht hier den meisten (auch mir!) natürlich um möglichst schnelle Ergebnisse.
Was besseres gibt es ja gar nicht.
Aber vor den Erfolg haben die Götter den Schweiß gesetzt!
Ich hab ja die Hoffnung noch nicht aufgegeben, daß einer vom Forum, der Ahnung hat, wie Werkzeugmaschinen ticken, dann auch mal in die Programmierung einsteigt und man sich ergänzen kann. Zwei Leute schaffen mehr als einer, fünf mehr als zwei.
Der Code eines fertigen C-Programms ist zum Abgewöhnen, keine Frage. Da sind mehr Unklarheiten versammelt als würden sich die Pychoanalytiker dieser Welt, ach was sage ich, im Umkreis von 100 km zu einem Kongress treffen.

Das liegt daran, daß man an einem fertigen Programm den Werdegang nicht mehr sieht. Es ist eben alles fertig und ausgefeilt, die dahinterstehende Logik ist dann nicht mehr so einfach erkennbar.
Daher möchte ich die Gelegenheit mal wahrnehmen, zu zeigen, wie ich (ich bin nicht repräsentativ, aber eine Möglichkeit unter vielen) so ein Projekt vorbereite, wie oben angekündigt, und das kommentieren. Ein Programm ist im Anfang noch übersichtlich.
Z. B. dieses hier, dessen erste Version (einfache Helix) wir ja oben schon gesehen haben.
Damit der Code nicht verhunzt wird, setze ich erstmal den Code rein, und dann nochmal eine Kopie vom Code, die ich dann zeilenweise erkläre.
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <fstream>
#include <sstream>
#include <stdlib.h>
using namespace std;
double sin_grad(double winkel);
double cos_grad(double winkel);
double const pi= 3.141592653589793238462643383279502884197169399375105820974944592 ;
long const aufloesung = 1000;
struct koordinaten
{
double xi[aufloesung],yi[aufloesung],zi[aufloesung]; //i=Innenhelix, Korkenzieherwindung
double xs[aufloesung],ys[aufloesung],zx[aufloesung]; //s=Satellit, die Drahtstärke
double resx[aufloesung],resy[aufloesung],resz[aufloesung]; //res=die resultierenden Koordinaten
};
koordinaten kn[aufloesung];
koordinaten *p =kn;
void berechne_koordinaten_innen();
void berechne_koordinaten_satellit();
void berechne_endkoordinaten();
void speichere_endkoordinaten();
int main(void) // *********************************main
{
system("PAUSE");
return EXIT_SUCCESS;
} //*********************************************** end main
double sin_grad(double winkel)
{
double zahl;
zahl=sin(winkel*pi/180);
return(zahl);
}
double cos_grad(double winkel)
{
double zahl;
zahl=cos(winkel*pi/180);
return(zahl);
}
void berechne_koordinaten_innen()
{
}
void berechne_koordinaten_satellit()
{
}
void berechne_endkoordinaten()
{
}
void speichere_endkoordinaten()
{
char buffer[80];
std::ofstream out ("doppelhelix.tap");
out << buffer << "\n";
}
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <fstream>
#include <sstream>
#include <stdlib.h>
using namespace std;
-> Für die Speicherung der Dateien mittels std::ofstream out braucht man erstaunlicherweise nicht fstream, sondern sstream. Warum das so ist, nicht fragen, einfach reinsetzen
double sin_grad(double winkel);
double cos_grad(double winkel);
-> das sind zwei alte Bekannte, die uns den ARCTAN=Bogenwinkel in Gradmaß umrechnen
double const pi= 3.141592653589793238462643383279502884197169399375105820974944592 ;
-> wir hängen in allem von pi ab. Immer liebevoll pflegen!
long const aufloesung=1000;
-> Jetzt folgt ein sehr guter Trick bei der Programmierung.
Würde man erstmal alles so in absoluten Zahlen setzen, wie man braucht, also 100, 500 oder sonstwas, käme man sehr ins Schleudern, wenn man das Programm ändern wollte. Dann müßte man alle diese Zahlen finden und ändern, und würde man eine davon übersehen, könnte sonstwas passieren.
Daher sehen wir an der OBERSTEN STELLE IM PROGRAMM GLOBAL schon mal die Globalen konstanten vor, wie z. B. auflösung, ungeachtet der Tatsache, daß diese sich natürlich auch ändern werden, AAAAAAAAAAABER: Wenn wir es so machen, müssen wir nur diese einzige Zahl ändern.
DENN:
Nachdem wir unsere erste Struktur erklärt haben, z. B. diese
struct koordinaten
{
double xi[aufloesung],yi[aufloesung],zi[aufloesung]; //i=Innenhelix, Korkenzieherwindung
double xs[aufloesung],ys[aufloesung],zx[aufloesung]; //s=Satellit, die Drahtstärke
double resx[aufloesung],resy[aufloesung],resz[aufloesung]; //res=die resultierenden Koordinaten
};
-> und mit kn die Variable dazu deklarieren, ist eben die Frage, wieviel Speicherplatz brauchen wir zu dieser Variable, und genau diese Frage beantworten wir nicht mit kn[500], sondern mit kn[aufloesung]. Das Programm nimmt das, weil wir aufloesung als KONSTANTE erklärt haben. Eine Konstante wird vom Compiler wie der Zahlenwert behandelt. Würden wir aber die Konstante ändern in 50000, würde die vom Compiler auch als Zahlenwert gehandelt. Daher also:
koordinaten kn[aufloesung];
koordinaten *p =kn;
-> Hier haben wir unseren alten Bekannten, uns3eren Pointer Peter, den wir jetzt mit p abkürzen, um kürzeren Code zu haben. Solche mnemotechnischen Tricks wie einen Pointer Peter zu nennen, ist gute Programmierpraxis, das prägt sich im K opf ein, daß *p dann eben Peter ist und nicht etwa pi.
void berechne_koordinaten_innen();
void berechne_koordinaten_satellit();
void berechne_endkoordinaten();
void speichere_endkoordinaten();
-> Hier sieht man, was in Planung ist. Wir wollen erst Koordinaten von der einen
Helix berechnen, dann die nächste, dann die Werte abgleichen und in endkoordinaten umrechnen, und dann den ganzen Kram speichern. Das ist an dieser Stelle formal schon mal vorbereitet, wir müssen diese Funktionen nur noch mit Leben erfüllen
int main(void) // *********************************main
{
system("PAUSE");
return EXIT_SUCCESS;
} //*********************************************** end main
-> MAIN IMMER SCHLANK HALTEN! Bloß keine Zeile mehr als muß! MAIN ist unser BRAIN, da muß alles übersichtlich sein. WAS IMMER MAN IRGENDWIE ALS FUNKTION AUSGLIEDERN KANN, GEHÖRT NICHT IN MAIN! In Main wird nur aufgerufen.
Daß ich main nicht als main() erkläre, sondern als main(void), liegt daran, daß iich gelesen habe, main() führt zu langsamerem Code, weil zum ganz alten Ritche-C gehörig, der Ansi standard verlangt entweder Argumente, oder wenn kein Argument drin steht, eben einen Platzhalter, das ist (void) Ob das stimmt, weiß ich nicht, zur Vorsicht erkläre ich das eben so.
double sin_grad(double winkel)
{
double zahl;
zahl=sin(winkel*pi/180);
return(zahl);
}
double cos_grad(double winkel)
{
double zahl;
zahl=cos(winkel*pi/180);
return(zahl);
}
void berechne_koordinaten_innen()
{
}
void berechne_koordinaten_satellit()
{
}
void berechne_endkoordinaten()
{
}
void speichere_endkoordinaten()
{
char buffer[80];
std::ofstream out ("doppelhelix.tap");
out << buffer << "\n";
}
-> Wir sehen die leeren Hüllen unserer vordefinierten Funktionen. Diese schon jetzt als leere Hülle zu formulieren, ist sehr gut. Wir wissen dann, die Klammerungen passen, der Compiler hat nichts zu meckern und können dann, erst dann,
WENN DER GANZE DEKLARATIONSTEILS FORMAL IN ORDNUNG ISt,
mit dem Programmieren beginnen.
Deklarationen sind auch Programmierung! Sogar ein sehr wichtiger Teil davon. Wir prüfen das mit einem Compilerdurchlauf, ob der auch alles richtig verstanden hat (und nicht meckert), damit wir FORMAL AUF DER SICHEREN SEITE SIND!
Denn:
eine einzige falsch gesetzte Klammer kann das ganze Programm ruinieren.
Daher ist die absolute strenge Zeichensprache von C ein weiteres Highlight dieser wirklich sehr schönen Sprache.
Der Beitrag wurde von sharky bearbeitet: 26.01.2009, 21:11 Uhr