Verleitet C++ zum komplizierteren denken?
-
otze schrieb:
Es soll ein neues Objekt hinzugefügt werden, das auf Basis einer beliebig schwingenden komplexen e-Funktion auf Basis von Polarkoordinaten dargestellt wird. Hierbei ist zu beachten, dass die Funktion periodisch in 2pi ist.
[...]Unter anderem auch Formen wie Kleeblätter. Ein Algorithmus zur numerischen Berechnung der Schnittpunkte existiert.)
Ich hoffe, damit habe ich alle möglichen Ausflüchte mit abgedeckt.was ist daran problematisch? Man definiert eine Klasse Polar mit Instanzvariablen r und abs, deren Instanzen so initialisiert werden:
p := Polar new r: f abs: g.
wobei f und g jeweils Blocks sind (Blocks sind in Smalltalk auch Objekte, können also als Parameter übergeben werde), etwa
f := [ :phi | 2 * phi ] "r(phi)" g := [ :phi | phi sin ] "abs(phi)"
Dann bekommt Polar eine Methode zum Berechnen der Schnittpunkte mit einem anderen 'Polar' - so ein Algo soll ja nach Vorauss. existieren:
p := Polar new r: f abs: g. q := Polar new r: h abs: i. p cutWith: q.
Schließlich braucht man noch eine Plot-Funktion - das ist kein Problem, man variiert t über
den Definitionsbereich und plottet die Funktionenx := p r value: t y := p abs value: t)
-
etwas unglückliche Bezeichner gewählt: r ist der Winkel, und phi ist die Laufvariable.
Mit den üblichen Bezeichnungen phi = Winkel, t = Laufvariable und abs = Betrag
sähe das so aus:p := Polar new phi: f abs: g. f := [ :t | 2 * t ] "phi(t)" g := [ :t | t sin ] "abs(t)" p := Polar new phi: f abs: g. q := Polar new phi: h abs: i. p cutWith: q. x := p phi value: t y := p abs value: t
aber das Prinzip ist klar.
Die Plotroutine wäre dann ungefähr von der Form:
Polar>>plot 1 to: 2 * (Float pi) by: 0.001 do: [ :t || x y | x := (phi value: t) sin * (abs value: t). "r * cos (phi) " y := (phi value: t) cos * (abs value: t). "r * sin(phi)" aCanvas plot x: x y: y. ].
-
und hier als Smalltalk-Code, vollständig bis auf den tatsächlichen Algo zum Berechnen
der Schnittpunkte, der hier nur als leerer proxy repräsentiert ist:"neue Klasse Polar ableiten" Object subclass: #Polar instanceVariableNames: 'phi abs' classVariableNames: '' poolDictionaries: '' category: '' "Methode zum Setzen der instance vars zufügen" Polar compile: 'phi: aphi abs: aabs phi := aphi. abs := aabs '. f := [ :t | 2 * t ] "f(t) = 2*t" g := [ :t | t sin ] "g(t) = sin(t)" "zwei Instanzen erzeugen" p := Polar new phi: f abs: g. q := Polar new phi: g abs: f. "Methode zum Berechnen der Schnittpunkt mit anderem Polar (nur proxy), Rückgabe als Array:" Polar compile: 'cutWithPolar: aPolar "... calc common points of self and aPolar ..." ^ Array new. '. "Schnittpunkte von p und q berechnen und als Array ausgeben:" arrayOfCommonPoints := p cutWithPolar: q. T show: arrayOfCommonPoints asString.
Ausgabe:
#()
muß man nur noch einen geeigneten Algo für die gemeinsamen Punkte in die
Methode Polar>>cutWithPolar: einsetzen, ansonsten fertig.
-
Ich vermisse irgendwie die Geraden, Kreise, Ellipsen und Quadrate.
-
weiß zwar nicht, wozu so eine Polar/kartesische Gemengelage sinnvoll sein soll, aber dazu bildet man eine Oberklasse "DrawElement" zu Strecke + Ellipsenbogen + Polar; deren Instanzen werden in einem Array gespeichert, das die Eingabe für den Schnittalgorithmus darstellt.
Geeignete Schnittalgorithmen zwischen den 3 Typen werden ja vorausgesetzt, also geht es nur noch darum, die Vereinigungsmenge aus den einzelnen Schnittpunktmengen zwischen je zwei "DrawElement" zusammenzusetzen, das paßt schon.
-
u_ser-l schrieb:
weiß zwar nicht, wozu so eine Polar/kartesische Gemengelage sinnvoll sein soll, aber dazu bildet man eine Oberklasse "DrawElement" zu Strecke + Ellipsenbogen + Polar; deren Instanzen werden in einem Array gespeichert, das die Eingabe für den Schnittalgorithmus darstellt.
Geeignete Schnittalgorithmen zwischen den 3 Typen werden ja vorausgesetzt, also geht es nur noch darum, die Vereinigungsmenge aus den einzelnen Schnittpunktmengen zwischen je zwei "DrawElement" zusammenzusetzen, das paßt schon.4 Typen, oder? Ellipsenbogen, Quadrat, Gerade, Polarzeug.
Wie findest Du aus einem der 16 möglichen eingehende Typtupel den richtigen der 6 Schnittalgorithmen?
-
u_ser-l schrieb:
weiß zwar nicht, wozu so eine Polar/kartesische Gemengelage sinnvoll sein soll
Das weiß ich auch nicht. Der Polarkram war nicht wirklich nötig.
-
volkard schrieb:
Wie findest Du aus einem der 9 möglichen eingehende Typtupel den richtigen Schnittalgorithmus?
(blaBla isMemberOf: Polar) ifTrue: [ self cutWithPolar: blaBla ] ifFalse: [ self cutWithLine: blaBla ].
Ellipsenbögen gehen in Polardarstellung, bleiben also die Kombinationen Polar/Polar, Polar/Strecke und Strecke/Strecke.
-
u_ser-l schrieb:
volkard schrieb:
Wie findest Du aus einem der 9 möglichen eingehende Typtupel den richtigen Schnittalgorithmus?
(blaBla isMemberOf: Polar) ifTrue: [ self cutWithPolar: blaBla ] ifFalse: [ self cutWithLine: blaBla ].
Ellipsenbögen gehen in Polardarstellung, bleiben also die Kombinationen Polar/Polar, Polar/Strecke und Strecke/Strecke.
Ist das jetzt nicht doch Double Dispatching aus dem Lehrbuch?
-
u_ser-l schrieb:
(blaBla isMemberOf: Polar) ifTrue: [ self cutWithPolar: blaBla ] ifFalse: [ self cutWithLine: blaBla ].
um das normale dispatching nochmal zu verwenden, könnte man auch dem anderen Objekt die aufbereitete Nachricht weiterleiten.
(blaBla isMemberOf: Polar) ifTrue: [ self cutWithPolar: blaBla ] ifFalse: [ self cutWithLine: blaBla ].
würde zu
(in der Klasse Polar)blaBla cutWithPolar: self
(in der Klasse Line)
blaBla cutWitLine: self
z.B. in der Klasse Polar wäre dann in cutWithLine klar, daß self ein polar und blaBla eine Strecke ist und man hätte den richtigen Algorithmus. Das würde man wohl anstreben, wenn man davon ausgeht, daß das eingebaute (single) Dispatching so ziemlich das beste ist, was man haben kann und daraus das double dispatching bauen will.
In C++ findet man auch beide Vorgehensweisen, das mit if sähe so aus(blaBla isMemberOf: Polar) ifTrue: [ self cutWithPolar: blaBla ] ifFalse: [ self cutWithLine: blaBla ].
wird zu
if(Polar* b=dynamic_cast<Polar>(blaBla)) return cutWithPolar(b); if(Polar* b=dynamic_cast<Line>(blaBla)) return cutWithLine(b); /*wenn hier, dann programmierfehler*/
Die Version mit dem Zurückschicken brauche ich nicht zu scheiben, die ist ja gleich.
-
;fricky schrieb:
tntnet schrieb:
C++ ist nicht einfach zu bedienen, aber wenn ich es beherrsche, also eine ausreichende Ausbildung erfahren habe, dann kann ich mit C++ mit einem angemessenen Aufwand die besten Applikationen der Welt machen.
da gebe ich dir recht, was immer auch die 'besten applikationen der welt' (oder von der welt, wie artchi sagen würde) sein mögen. aber leider trifft dein argument auf 99.9% aller sprachen zu, der unterschied liegt nur in der einfachheit der bedienung und dem damit verbundenen aufwand.
99,9% der besten Programme wurden aber aus guten Grund mit C++ geschrieben. Nämlich weil 99,9% der Programmiersprachen eben nicht dafür geeignet sind.
Wenn Du mit dem Profitool C++ nicht umgehen kannst, dann lass es einfach und bleib bei Deinen leicht zu lernenden Hobbysprachen, die Dein Intelektuell nicht überfordern
. Und hör endlich auf, über das Profiwerkzeug C++ zu lästern, womit Du nicht umgehen kannst. C++ ist nicht schlecht, nur weil Du C++ nicht verstehst.
Ich wundere mich überhaupt, warum Du Dich hier im C++-Forum rumtreibst, wenn Du der Meinung bist, C++ sei schlecht.
-
tntnet schrieb:
die Dein Intelektuell nicht überfordern
-
tntnet schrieb:
;fricky schrieb:
tntnet schrieb:
C++ ist nicht einfach zu bedienen, aber wenn ich es beherrsche, also eine ausreichende Ausbildung erfahren habe, dann kann ich mit C++ mit einem angemessenen Aufwand die besten Applikationen der Welt machen.
da gebe ich dir recht, was immer auch die 'besten applikationen der welt' (oder von der welt, wie artchi sagen würde) sein mögen. aber leider trifft dein argument auf 99.9% aller sprachen zu, der unterschied liegt nur in der einfachheit der bedienung und dem damit verbundenen aufwand.
99,9% der besten Programme wurden aber aus guten Grund mit C++ geschrieben. Nämlich weil 99,9% der Programmiersprachen eben nicht dafür geeignet sind.
Das denke ich nicht. Für große Projekte sind vor allem die vorhandenen Tools (dazu zähle ich sowohl vorhandene Libs als auch Tools an sich, z.b. IDEs) und deren Support wichtig, und da sieht es bei C++ eindeutig am besten aus. Auch geschulte Leute gibts für C++ wahrscheinlich mehr als für Brainfuck.
Die Tatsache, dass sich so eine Masse an Tools und Anhängern für C++ entwickelt hat, muss nichtmal an der Sprache selbst liegen. Es ist selbstverständlich, dass sich in der Industrie einige wenige Sprachen durchsetzen müssen, die überall verwendet werden (natürlich mit Ausnahmen wie Sprachen die für Nischenanwendungen benötigt werden), aus Einfachheits- und natürlich Kostengründen. Dass das nicht unbedingt mit der Eleganz oder der Performance, sprich dem "Look and Feel" einer Sprache zu tun haben muss, sieht man ja bei uns. Java, C++, C#, C werden alle reichlich benutzt, obwohl sie sehr unterschiedlich sind.
Natürlich wird sich dabei sowas wie Brainfuck nicht durchsetzen, aber C++ ist sicherlich nicht das Non-Plus-Ultra und trotzdem wird sie sich wahrscheinlich gegenüber kommenden "besseren" Nischensprachen besser halten.
-
;fricky schrieb:
Burkhi schrieb:
Bei einen Microcontroller reicht es ja auch meistens aus, diesen in Assembler oder C zu programmieren, weil man solch hohe Anforderung an diesen meist gar nicht stellt.
was meinst du wohl, welche anforderungen an die gestellt werden? meistens arbeiten sie 24/7 an ihrer leistungsgrenze, der code muss kompakt, performant, sparsam mit RAM umgehen und 'direkt' sein. solche hohen anforderungen werden an PC-programme fast nie gestellt.
Kannst du bitte mal ein Beispiel geben, wo ein Microcontroller ständig an seiner Leistungsgrenze arbeitet? Was für Anforderungen sind das und was meinst du mit 'direkt'?
-
volkard schrieb:
(blaBla isMemberOf: Polar) ifTrue: [ self cutWithPolar: blaBla ] ifFalse: [ self cutWithLine: blaBla ].
Ist das jetzt nicht doch Double Dispatching aus dem Lehrbuch?
eine Art Simulation von double-dispatching. Der Standard-Mechanismus zur Auswahl der Methode zur Laufzeit ist single-dispatched, weil das 1. Argument einer message (der receiver) darüber entscheidet, welche Methode veranlaßt wird - es wird einfach im Methoden-Verzeichnis des receivers nach einem passenden Eintrag gesucht und aufgerufen.
Die "Typweiche" mit isMemberOf: läßt sich übrigens auf folgende OO-gemäße Weise vermeiden:
Man definiert eine Klasse "pairOfDrawElement", die als Unterklassen die Typenpaare "pairLinePolar", "pairPolarPolar" und "pairLineLine" enthält. Jede Unterklasse implementiert die Methode "cut".
Zur Datenstruktur "Figure" (Array von n Strecken, Bögen usw.) wird dann ein Array vom Typ "ArrayOfPairOfDrawElement" hergestellt, daß die n^2 Paare aus Strecke/Bogen, Strecke/Strecke, Bogen/Bogen
enthält.Der Algo "cutWith: aFigure" stellt dann zunächst das zugehörige ArrayOfPairOfDrawElements her und ruft dann nacheinander deren spezifische Schnittmethoden auf:
anArrayOfPairOfDrawElements do: [ :each | each cut ]. "isMemberOf: oder isKindOf: nicht mehr nötig."
Übrigens ist es möglich, in Smalltalk double- und multiple-dispatch zu implementieren, das geht in Smalltalk selbst (wenn auch mit geringerer Performance) ohne daß die VM oder die Sprache dazu geändert werden muß.
-
tntnet schrieb:
99,9% der besten Programme wurden aber aus guten Grund mit C++ geschrieben. Nämlich weil 99,9% der Programmiersprachen eben nicht dafür geeignet sind.
das ist nichts anderes, als eine vorlaute behauptung von dir, die du niemals begründen kannst. was sollen denn die 'besten programme' sein? und sag jetzt nicht dein in C++ gestricktes web-framework. du wirst sicherlich sofort einsehen, dass andere (nicht C++ basierte) webtechnologien, deiner software haushoch überlegen sind.
Burkhi schrieb:
Kannst du bitte mal ein Beispiel geben, wo ein Microcontroller ständig an seiner Leistungsgrenze arbeitet? Was für Anforderungen sind das...
z.b. in produktionsanlagen die praktisch das ganze jahr durchlaufen, zur messdatenerfassung, telemetrie, datalogging, etc. werden welche eingesetzt. die laufen unter vollast, pumpen gewaltige datenmengen durch die gegend und werden so gut wie nie ausgeschaltet. und auch sonst eigentlich in jeder komplexen technischen anlage, sei es nun im kfz oder in deiner waschmaschine für steuerungsaufgaben usw. die dürfen nicht einfach so abkacken, wie ms-windows oder der media-player. d.h. die anforderungen (an die software), was stabilität und bugfreiheit angeht, sind viel höher als beim pc-frickelkram. bei end-user embedded-zeugs wie handys z.b. kommt aber auch wieder mit der heissen nadel (c++?) gestrickte software zum einsatz.
-
;fricky schrieb:
... sei es nun im kfz oder in deiner waschmaschine für steuerungsaufgaben usw. die dürfen nicht einfach so abkacken ...
Schon richtig, aber das Gros der Prozessoren langweilt sich eher zu Tode. Was in den meisten Reiskocherapplikationen drinsteckt, ist meilenweit überdimensioniert.
Aber wenn was einfach und effektiv erledigt werden kann, naht schon Rettung: Ich hab' mal eine Getriebesteuerung mit einem 68HC11 und ein paar hundert Bytes ASM- Code gelöst, das Ding hatte noch so viel Luft, daß´ich auch noch fünf andere mitversorgen hätte können. Für eine kleine Erweiterung wurde ein visuelles Softwaredesigntool ausprobiert, womit man nach zehn Minuten Umeinanderklicken z.B. eine Schleife hinbekam, raus kam dann ziemlich viel P-Code, den das Target interpretieren durfte. Der C167 hat das gerade mal so für ein Getriebe hinbekommen, aber der ist aber auch um Dimensionen schneller als ein HC11.
Ähnlich geht es bei der Industrieautomatisierung zu. SPS wurde als Dödel- Programmiersprache für vertrottelte Einrichter geschaffen und markiert so ziemlich den Gipfel an Ressourcenvergeudung. Ein Schleifautomat bei einem Nachbarbetrieb z.B. ist so ein Teil, wo alles so langsam zugeht, daß sich ein PIC mit'm Uhrenquarz die meiste Zeit schlafen legen könnte, tatsächlich werkelt in der SPS ein 68030 mit 50 MHz unter Vollast. Ein einmal eingeschlagener Irrweg wird dann über Step-3/5/7 zum wirrköpfigen Wahnsinn ausgebaut und weil den kaum ein Mensch in der eigentlichen Zielgruppe mehr direkt programmieren kann, mit grafischen Konfigutrationstools zugeklatscht. An komplexeren Problemen habe ich dennoch etliche erfahrene Teams scheitern gesehen. :p
Aber immerhin: Das Zeug muß 24/7 funktionieren und das tut es, auch wenn das Grundkonzept pure Prozessorbeschäftigungstherapie ist.
Um den etwas weiten Bogen zu schließen: Es scheint Menschen zu geben, denen schlichte, effektive Lösungen Unbehagen verursachen. Da muß dann weiter gefasst werden als nötig, bis man aus einer einfachen Sache einen aufgeblasenen Popanz gemacht hat. Und wie man sieht, braucht man nichtmal C++ dazu.
-
Meine Erfassungspunkte, die ich für VW entwickelt habe, laufen in der Produktion 7 Tage rund um die Uhr, seit 2003 ist der älteste im Einsatz, und bisher gabs, obwohl die alle unter Windows laufen, nie Probleme damit. Das soll zeigen, dass es auch mit dem "Frickel C++ Builder" durchaus möglich ist, stabile und zuverlässige Programme sogar unter "Frickel-" Windows zu schreiben. Einen Ausfall in der Produktion kann sich VW nicht leisten, warum gehen sie dann so ein "Risiko" ein?
Unsere Stellwerksrechner und Bedienplatzsysteme (mit sicherer Anzeige), die nach SIL4 eingestuft sind, wurden auch in C++ programmiert, die Bedienplätze laufen auch unter Windows, der Stellwerkskern unter einen Unix-System, mit A und B Code und zusätzlich noch je eine Intel und Power PC Plattform. Wären C++ Programme wirklich so mit der heissen Nadel gestrickt, würden diese Systeme niemals eine Zulassung des EBA bekommen.
Damit schliess ich auch meinen Teil zur Diskussion ab, manche Leute leben nun mal in ihrer kleinen Welt, und solange sie da glücklich sind, sollte man sie auch glücklich sein lassen.
-
OK ich hab mir hier garnichts durchgelesen, aber ich muss sagen das was du auf Seite beschreibst, das habe ich genau so erlebt. Desshalb überlege ich mir auch zweimal bevor ich ein Projekt in C++ Anfange.
-
pointercrash() schrieb:
Das Zeug muß 24/7 funktionieren und das tut es, auch wenn das Grundkonzept pure Prozessorbeschäftigungstherapie ist.
Welches Grundkonzept denn nun?