Programmierung Mathematik |
15.02.2016, 17:32 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
Programmierung Mathematik Dort wird gleich auf einer der ersten Seiten folgender Code für C++ gezeigt: LINK Ich verstehe dort kein Wort. Warum muss ein Primzahltest so unnötig lang und kompliziert sein, könnte mir jemand den Code näher erläutern. Im Skript steht ausdrücklich drin, dass C++ in der Vorlesung nicht näher erklärt wird. Meine Frage ist dann, wie soll jemand, der sich vorher nicht auskennt das meistern. Wenn man den Vorlesungsstoff und die Programmiersprache lernen muss??? |
||||||||||||
15.02.2016, 17:53 | IfindU | Auf diesen Beitrag antworten » | ||||||||||
RE: Programmierung Mathematik Traditionell wird in Bonn vor Vorlesungsbeginn ein 2 wöchiger Programmierkurs angeboten, bei dem alles wichtige vermittelt wird. |
||||||||||||
15.02.2016, 18:29 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
Und in zwei Wochen kann man soviel lernen, dass man das versteht wenn das der Professor runterrattert. Das heißt es wird einem dann in AlgorithMath.1 einfach der Code gesagt und BASTA und nicht mehr erläutert. Selbst bei einem Beweis sagt man ja noch jetzt macht man das und dan macht man das. |
||||||||||||
15.02.2016, 18:40 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||||||
Wirklich interessant ist doch nur die Funktion "primality_check" - der Rest ist Ein- und Ausgabe sowie das obligatorische Hauptprogramm "main", welches den Programmstart darstellt. Und "primality_check" selbst ist doch sehr einfach aufgebaut und im wesentlichen auch schon kommentiert (alles nach // bis Zeilenende). Wichtig zu wissen ist noch, dass % in C/C++ der Modulo-Operator ist. |
||||||||||||
15.02.2016, 18:44 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
Und warum steht dann über diesem Primzahltest nochmal extra die Beschreibung was da gemacht wird, also dieses bool_primal... und warum ist da nochmal von get_input die Rede?? |
||||||||||||
15.02.2016, 18:44 | IfindU | Auf diesen Beitrag antworten » | ||||||||||
Natürlich wird etwas dazu gesagt. Aber das meiste von dem Code hat nichts mit dem Algorithmus zu tun. Die erste Funktion ist der Algorithmus, und da ist sowohl kommentiert, als auch im Algorithmus 1.7 in Worten ausgedrückt. Und natürlich muss man es nicht in der Vorlesung verstehen. Die muss man nacharbeiten, und es gibt Übungen. Dort kann man auch Tutoren fragen. |
||||||||||||
Anzeige | ||||||||||||
|
||||||||||||
15.02.2016, 19:33 | RavenOnJ | Auf diesen Beitrag antworten » | ||||||||||
Der Code ist so einfach, dass man ihn nach einem höchstens 1-wöchigen Kurs in C lesen kann (C++ braucht man dafür noch nicht mal wirklich; nur ,,std::cout <<", ,,std::cin >>" ist C++, der Rest C). Eigentlich muss man hier nur die Funktion primality_check verstehen, die (etwas ineffektiv programmiert) in einer Schleife alle Zahlen von 2 bis testet, ob sie Teiler von n sind. |
||||||||||||
15.02.2016, 19:35 | outSchool | Auf diesen Beitrag antworten » | ||||||||||
RE: Programmierung Mathematik Hallo leoclid!
Ich nehme Bezug auf deinen Thread Beste Programmiersprache für Einsteiger und Mathematik. Ich mache dir mal den Vorschlag, wenn du schon an C++ interessiert bist, dich zuvor mit C auseinanderzusetzen, und zwar im Hinblick auf "Prozedurale Sprachen". Einen ersten Hinweis findest du in wikipedia unter Prozedurale Programmierung. Warum "Prozedurale Sprachen" und nicht C++ oder Java oder ... ? Weiss man einmal welche Elemente und Strukturen eine "Prozedurale Sprache" hat, ist es einfach sich in andere Programmiersprachen einzuarbeiten. Circa 80% hat man durch das Verstehen einer "Prozeduralen Sprache" abgedeckt. Der Rest sind Erweiterungen wie sie typisch für Datenbanksprachen oder Objektorientierung sind. Meine C-Kenntnisse liegen schon 20 Jahre zurück, aber das Code-Snippet, das dir zu schaffen macht, verstehe ich ohne groß zu überlegen. Schöne Grüße outschool |
||||||||||||
15.02.2016, 19:39 | RavenOnJ | Auf diesen Beitrag antworten » | ||||||||||
Dass man den Code in mehrere Funktionen mit verschiedenen Verantwortlichkeiten aufgespaltet hat, ist im Sinne einer sauberen Codestrukturierung. Offenbar wird dort darauf Wert gelegt. Zum Glück! Macht man das nicht und hat ein etwas größeres Programm, dann blickt man nach kurzer Zeit nicht mehr durch, was das Programm eigentlich macht. |
||||||||||||
15.02.2016, 19:54 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
Aber warum macht man das Ganze mit bool primality_check(int n) und so weiter es geht doch auch viel einfacher |
||||||||||||
15.02.2016, 20:01 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||||||
Nicht dauernd nur meckern, sondern zeigen. |
||||||||||||
15.02.2016, 20:03 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
Wo kann ich mir denn das ganze Grundwissen aneignen. Was definiert der denn da das ganze Zeit? Sorry, ich will jetzt nicht durchgeknallt klingen, aber warum kehren die zu n zurück? |
||||||||||||
15.02.2016, 20:09 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||||||
Du klingst aber durchgeknallt, wenn du nicht erklärst, wer wie wo "zu n zurückkehrt". |
||||||||||||
15.02.2016, 20:14 | RavenOnJ | Auf diesen Beitrag antworten » | ||||||||||
RE: Programmierung Mathematik
Und warum nicht mal eine funktionale Sprache wie Haskell? Die Funktion primality_check könnte man dann so schreiben:
Ich will allerdings nicht behaupten, dass das einfacher zu verstehen wäre, obwohl ich den Code fast selbsterklärend finde, sobald man weiß was head, filter und map machen. (Hier hätte man sogar per lazy evaluation gleich die Ineffektivität in primality_check erschlagen, dass nämlich dort immer alle Zahlen bis durchgeackert werden.) |
||||||||||||
15.02.2016, 20:21 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
Ich würde aber gerne erst einmal den Code in C++ oben verstehen. Bin ich wirklich zu blöd dafür warum man die ganzen Extra Sachen braucht? Wo wird so etwas erklärt? |
||||||||||||
15.02.2016, 20:30 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
Ich versuche mal Stück für Stück meine Probleme zu schildern: Der erste Teil mit dem Primality Check ist soweit klar, aber [/B] bool primality_check(int n) Ist das vorgegeben, dass das Programm das kennt, warum schreibe ich es denn als Überschrift oben drüber Warum return result;, ich habe doch jetzt schon mein Ergebnis. Und danach verstehe ich einfach nicht mehr was die ganzen Überschriften sollen, und warum der int main() part ganz zum Schluss kommt und warum ich überhaupt eine Variable brauche, die main heißt. Ich bin echt am verzweifeln. Ich habe in Mathematik sonst nie Probleme, aber warum bereitet mir das Programmieren so große Schwierigkeiten? |
||||||||||||
15.02.2016, 21:00 | Steffen Bühler | Auf diesen Beitrag antworten » | ||||||||||
Dieses Programm besteht aus vier einzelnen Unterprogrammen. Siehst Du die? Drei davon geben einen Wert zurück, eines nicht. Siehst Du, welches? Zwei verlangen einen Übergabewert, zwei nicht. Siehst Du, welche? Das Schlüsselwort "main" bezeichnet die Stelle, bei der das Programm beginnt. |
||||||||||||
15.02.2016, 21:01 | RavenOnJ | Auf diesen Beitrag antworten » | ||||||||||
Was heißt hier ,,Überschrift"? 'primality_check' ist der Name der Funktion, das Ganze ,,bool primality_check(int n){...}" ist die Defintion dieser Funktion.
Das ist halt C. Die Rückgabe des Ergebnisses erfolgt über ein return-Statement.
s.o., das sind Funktionsnamen.
Die main()-Funktion ist notwendig. Sie signalisiert über ihren Namen dem Compiler den Einstiegspunkt für das Programm.
Das kann dir hier niemand beantworten, aber ich vermute mal, dass du dich überhaupt noch nicht wirklich mit C oder C++ beschäftigt hast. Lies mal ein Einstiegsbuch zu dem Thema, ,,C++ for dummies" oder sowas (wobei ich dieses Buch nicht kenne und auch nicht empfehlen möchte.). Empfehlenswert ist auf alle Fälle der Klassiker von Kernighan, Ritchie The C Programming Language |
||||||||||||
15.02.2016, 21:06 | 10001000Nick1 | Auf diesen Beitrag antworten » | ||||||||||
Ich kann dir auch C von A bis Z empfehlen. Damit habe ich damals C gelernt; und es hat den Vorteil, dass es online verfügbar ist. |
||||||||||||
15.02.2016, 21:18 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
Aha, ich glaube jetzt habe ich es in etwa raus: Die erste Anweisung ist, dass int n = get_input() ist. Also führt er diese Funktion aus und gibt das n an die Main Funktion zurück. Die zweite Anweisung ist es, dass bool n_is_prime = primality_check(n) also die Bool Variabele n_is_prime, das Ergebnis des primalit_check(n) ist, nun führt das Programm diese Funktion durch mit dem Parameter, der bei der ersten Anweisung herausgekommen ist und gibt das Ergebnis zurück. Die letzte Anweisung ist es nun, den Output zu schreiben, mit genau den Paramtern, die die ersten beiden ausgeführten Funktionen zurückgegeben haben. Die einzige übrige gebliebene Frage ist nun, warum es if (answer) { std::cout << n << " is prime.\n"; } heißt, müsste das nicht mit if (n_is_prime=false) beginnen? |
||||||||||||
15.02.2016, 21:34 | Steffen Bühler | Auf diesen Beitrag antworten » | ||||||||||
Wenn überhaupt, dann "if (n_is_prime==true)". Der Vergleichsoperator ist "==", das "=" würde die Variable auf true setzen, denn es ist eine Zuweisung. Und wenn es wahr ist, dass die Zahl prim ist, soll "is prime" geschrieben werden, nicht wenn es falsch ist. Aber das Unterprogramm write_output kennt die Variable n_is_prime überhaupt nicht! Es weiß nur was von seinen Parametern n und answer. Und nur mit denen kann es umgehen. |
||||||||||||
15.02.2016, 21:48 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
aber wo wird denn die Variable bool answer definiert? |
||||||||||||
15.02.2016, 21:53 | Steffen Bühler | Auf diesen Beitrag antworten » | ||||||||||
In der Parameterliste von write_output. Siehst Du das? Dieses Unterprogramm erwartet eine int und eine bool. Wie der Aufrufer die nennt, ist dem Unterprogramm egal, es selbst kennt sie als n und answer, solange es läuft. |
||||||||||||
15.02.2016, 21:54 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
Aber eine bool ist doch true oder false. Schließlich liefert doch auch die erste Funktion ein true oder false zurück?? |
||||||||||||
15.02.2016, 22:00 | Steffen Bühler | Auf diesen Beitrag antworten » | ||||||||||
Du meinst, weil da nicht steht "if (answer==true)", sondern nur "if (answer)"? Nun, das ist dasselbe! Das "if" erwartet doch schon eine bool, die wahr oder falsch ist. Es wäre nicht direkt falsch, die vorher auf true zu prüfen und dieses Ergebnis zu verwenden. Aber doppelt gemoppelt. C ist nicht so geschwätzig. |
||||||||||||
15.02.2016, 22:13 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
Aber if(answer)?? Wenn Antwort? Es gibt immer eine Antwort, wenn es eine Primzahl ist und wenn es keine Primzahl ist. |
||||||||||||
15.02.2016, 22:20 | Steffen Bühler | Auf diesen Beitrag antworten » | ||||||||||
Ja, der Name der Variable "answer" ist in der Tat unglücklich gewählt. Aber Name ist auch hier Schall und Rauch. Die Variable könnte auch "Heinz" heißen: wenn sie auf true steht, wird "is prime" geschrieben, sonst "is not prime". |
||||||||||||
15.02.2016, 22:47 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
Ich verstehe das immer noch nicht so ganz. Ausgeführt werden soll: write_output(n, n_is_prime) und die Variable "n is prime" kann doch nur die Werte true oder false annehmen. Warum wechsle ich dann plötzlich zu void write_output(int n, bool answer). Ich habe nie definiert, welche Werte die bool Variable "answer " annehmen kann. Und da steht ja if(answer), aber die Variable kann doch nicht den Wert answer annehmen, sie heißt answer. |
||||||||||||
15.02.2016, 22:50 | RavenOnJ | Auf diesen Beitrag antworten » | ||||||||||
In der Klammer von if(...) muss ein boolscher oder ganzzahliger Ausdruck stehen. Das heißt, ein Ausdruck der als true oder false oder als ganze Zahl evaluiert wird. Beispielsweise if(true) oder if(expression), wobei expression vom Typ bool oder von einem integralen Typ sein muss. Es ist also auch erlaubt int a; if(a){...} zu schreiben. Bei einem ganzzahligen Typ bedeutet 0 false und alle anderen Werte true. Wissenswert ist dabei, dass es in C überhaupt keinen boolschen Typ gibt, den gibt es erst in C++. |
||||||||||||
15.02.2016, 22:52 | RavenOnJ | Auf diesen Beitrag antworten » | ||||||||||
Genau, sie heißt answer. Das ist nur ein Name für diese Variable, kein Wert. Diese Variable kann aber nur die Werte true oder false annehmen. Edit: Vielleicht solltest du dir mal klarmachen, was bei einem Funktionsaufruf auf Maschinenebene passiert. Was in diesem Zusammenhang ein Call-Stack ist, wie dort die Aufrufparameter angelegt werden usw.. Vielleicht wird dir dann manches klarer. Wie die Variablen heißen ist auf Maschinenebene vollkommen irrelevant. Die Namen sind nur Informationen für den Compiler, damit der das Programm richtig in Maschinencode umsetzt. |
||||||||||||
15.02.2016, 22:56 | leoclid | Auf diesen Beitrag antworten » | ||||||||||
Ja, sie kann nur die Werte true oder false annehmen. Deswegen verstehe ich das if(answer) nicht. Was ist damit gemeint? Wenn die Variable answer was ist? Wenn sie einfach nur da ist? If muss doch immer etwas prüfen. |
||||||||||||
15.02.2016, 23:08 | Nofeys | Auf diesen Beitrag antworten » | ||||||||||
Ja, es prüft genau, ob das, was in den Klammern steht, wahr oder falsch ist. In unserem Fall ist 'answer' genau ein solcher Wahrheitswert. Wenn die Variable 'answer' den Wert 'true' hat, wird also der Codeblock ausgeführt, sonst nicht. |
||||||||||||
15.02.2016, 23:08 | RavenOnJ | Auf diesen Beitrag antworten » | ||||||||||
Ja, es prüft den Inhalt der Variablen 'answer'. Der kann true oder false sein. Insofern kann man schreiben if(answer == true) oder if(answer) was dasselbe bedeutet. Es könnte im Code auch irgendwo if(answer == false) oder gleichwertig if(answer != true) oder auch if(!answer) stehen. Alles würde als true ausgewertet, wenn 'answer' den Wert false hat. Das Ausrufezeichen ! bedeutet in C/C++ 'not', also die logische Verneinung. |
||||||||||||
15.02.2016, 23:38 | Dopap | Auf diesen Beitrag antworten » | ||||||||||
in C kann man durchaus "unleserlich" programmieren. Wir hatten früher in der Wirtschaftsinformatik mit TurboPascal gearbeitet, welches wesentlich strenger in den Deklarationen ist. Für Einsteiger zu empfehlen. |
||||||||||||
15.02.2016, 23:44 | RavenOnJ | Auf diesen Beitrag antworten » | ||||||||||
Pascal wird nur heute noch nicht mal mehr an der Uni verwendet. Stattdessen Java, Python, C, C++. |
||||||||||||
16.02.2016, 09:26 | Steffen Bühler | Auf diesen Beitrag antworten » | ||||||||||
Schlimmer: wer heute mit C++ arbeiten will, bekommt, jedenfalls mit Bordmitteln unter Windows, kaum noch einen anständigen Compiler. Diese Sprache erleidet gerade dasselbe Schicksal wie Pascal Ende der Neunziger. Oder Fortran Ende der Achtziger. Wer heutzutage Programme (also exes) mit einigermaßen brauchbarer Benutzeroberfläche programmieren will, greift zu .NET. Und das hat lange das Trio C++, C# und Basic unterstützt, aber C++ wird immer holpriger und ist da kaum noch zu gebrauchen. Gewiss, in der Mathematik, wo es weniger auf Buttons und Schieberegler ankommt, kann man mal schnell ein Konsolenprogramm schreiben, aber bei professionelle GUIs wird es schnell unangenehm. Und so musste auch ich mich mit dem redseligen C# anfreunden und sogar schon wieder mal Basic schreiben, weil Kollegencode zu unterstützen war. Natürlich hat dieses Basic nichts mehr mit früher zu tun, es ist eigentlich fast dasselbe wie C#, nur ohne Semikola. Was ich zusammen mit Raven schlimmer finde, ist, dass heutige Programmierer nicht mehr wissen müssen,
Das ist Segen wie auch Fluch. Was wurde uns eingetrichtert, wenn etwas mit new allokiert wurde, es zum Schluss auch ja brav mit delete wieder zurückzugeben. Keine Megabytes als Parameter zu übergeben, sondern einen schönen Zeiger dadrauf. Und globale Variablen waren sowas von bäh. Was haben wir jetzt? Überall wird mal eben kurz ein Array oder Image angelegt, delete gibt es gar nicht mehr, macht alles der garbage collector. Speicher ist schließlich genügend da. Ob eine Routine wie die im Beispiel angeführte auch unnötigerweise gerade Zahlen prüft, ob sie prim sind, ist egal, der Prozessor ist doch so schnell, dass man's eh nicht merkt. Globale Variablen im strengeren Sinne gibt es zwar nicht, aber da man gleich eine Klasse angelegt bekommt, definiert man alles, was man braucht, da drin und lässt alle Routinen auch lustig drauf zugreifen, wie früher eben auch. Datenkapselung ist was anderes. Aber genug OT-Gejammer. So wird nun mal heute programmiert. Einen Autofahrer interessiert auch nicht mehr, bei welchem Winkel sein Zündzeitpunkt liegt. Hauptsache, die Kiste fährt. Viele Grüße Steffen |
||||||||||||
16.02.2016, 10:02 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||||||
Es soll auch noch ein paar Leute geben, die verwenden dafür Qt. |
||||||||||||
16.02.2016, 10:34 | RavenOnJ | Auf diesen Beitrag antworten » | ||||||||||
Das war mir auch sofort eingefallen. Wobei ich allerdings für GUIs eher Java bevorzuge, vor allem mangels Kenntnissen in Qt-Programmierung . @Steffen Ich würde auch das Schicksal von C++ nicht mit dem von Pascal vergleichen. Pascal war immer nur im Uni-Umfeld stark, nie in der Industrie. C++ hat immerhin breite Industrieunterstützung, nicht zuletzt MS, und ist immer noch eine der wichtigsten Programmiersprachen (Tiobe Index; die Methodik der Indexerstellung ist allerdings mMn etwas fragwürdig; das hohe Gewicht von Java und C kommt mMn von zu häufigen studentischen Googeleien). Unter anderem mit dem gcc gibt es einen sehr guten Compiler, auch für C++11. Diverse IDEs (eclipse, netbeans etc.) sind geeignet. Wie ich überhaupt C++ (mit C++11, aber erst seitdem ) als eine wieder durchaus attraktive Programmiersprache ansehe. Davor eher als pain in the ass. Aber das ist wohl Geschmacksache. Deinen Rant über new, delete usw. kann ich ein wenig nachvollziehen, bin aber froh, dass es in C++11 sowas wie unique_ptr gibt, was einem das Leben durchaus erleichtern kann. Das hat auch nichts mit Garbagecollection zu tun. |
||||||||||||
16.02.2016, 12:16 | RavenOnJ | Auf diesen Beitrag antworten » | ||||||||||
Ich vermute, die inneffektive Implementierung von primality_check ist einer möglichst einfachen Darstellung für Anfänger geschuldet. Es ist klar, dass es einige Möglichkeiten zur Optimierung und Beschleunigung gibt. Die Prüfung mit allen geraden Zahlen, wie überhaupt die Prüfung mit allen Zahlen bis , ist allerdings ziemlich hanebüchen. Da hätte man auch sofort ohne große Verkomplizierung schreiben können:
|
||||||||||||
13.01.2017, 02:01 | RavenOnJ | Auf diesen Beitrag antworten » | ||||||||||
RE: Programmierung Mathematik Da ich meinen damaligen Post vom 15.02.16 20:14 nicht mehr editieren kann, hier eine Codeverbesserung. sqrt für sehr große Zahlen zu verwenden wäre einfach falsch. Die verbesserte (aber immer noch ineffiziente) Funktion primalityCheck sollte man mit Hilfe von sqrRoot besser so schreiben:
|
|
Verwandte Themen
Die Beliebtesten » |
|
Die Größten » |
|
Die Neuesten » |
|