Programiersprache für Anfänger



  • ~fricky schrieb:

    asc schrieb:

    aber bei einen sinnvollen Buchaufbau hat auch der C++ Einsteiger ab dem ersten Kapitel sichtbare Erfolgserlebnisse.

    das halte ich für ein gerücht. im ersten kapitel lernt der einsteiger grundlagen wie verschiedene datentypen, operatoren, kontrollstruktoren, etc. alles recht trocken. was kann er nach dem letzen kapitel? maximal ein konsolenprogramm, z.b. einen taschenrechner programmieren, der überladene operatoren benutzt. sowas haut heute keinen mehr vom hocker.
    🙂

    Und in einem Java/C#-Buch lernt er im ersten Kapzeil, wie er ganz einfach sein erstes ERP-Programm mit GUI und RDBMS-Anbindung baut, ohne trockene Operatoren & Co.
    Damit ist er bestens gerüstet, für seine erfolgreiche Entwicklerlaufbahn.

    Mensch, sind wir alle doof, die umsonst gelernt haben, was elementare Datentypen, Operatoren, Kontrollstrukturen usw. sind.



  • HansiHinterseher schrieb:

    Schön für den Hobby-Programmierer. Aber beruflich könnte sojemand bei uns in den Projekten nichts anfangen. Er würde bei den Mindestanforderungen für OSGi und Eclipse-RPC im Boden eingestampft werden.

    mensch Artchi, es geht darum, dass er 'bei der stange bleibt'. jemand, der von vorn herein spass an einer sache empfindet (und das funktioniert bei den meisten menschen nur über sichtbare erfolgserlebnisse), wird mit freude weiter machen und will immer mehr darüber wissen. die chance ist viel höher, dass so jemand, irgendwann später, professionell programme schreibt, als bei einem, der sich mühsam den stoff reinquält und kaum reale ergebnisse hat. sicherlich gibt es auch leute, die höchste glücksgefühle haben, wenn sie sich mit total abstrakten dingen beschäftigen. aber die sollten vielleicht besser philosophen oder mathematiker werden.
    🙂



  • ~fricky schrieb:

    ~john schrieb:

    Warum sollte dies langsam sein?

    weil vor vielen rechenoperationen abgefragt werden müsste, ob ein undefiniertes ergebnis entstehen kann (und eine arithmetic-exception o.ä. müsste losgetreten werden).

    Korrekt betrachtet müßte man dies immer tun, da nur so die korrekte Funktionsweise des Programm gewährleistet ist. Für einige dieser Probleme z.B. div 0 bieten die meisten CPUs Hardware Interrupts an, so daß man ohne jeden Geschwindigkeitsnachteil so einen Test einbauen kann.



  • muemmel schrieb:

    Ich lese hier immer, daß Programmentwicklung mit C# oder Java so viel schneller gehen soll als mit C++.

    Die Frameworks für Java sind sehr viel umfangreicher als für C++, und die IDEs erzeugen massenweise Code für diese Frameworks auf Knopfdruck. Früher hat man GUIs ohne GUI-Builder geschrieben, in dem man schön von Hand den Code eingetippt hat. Heute würde niemand mehr auf diese Idee kommen. So ähnlich sieht es in vielen anderen Bereichen aus. Während man in den meisten C++ Projekten sich einen Wolf programmiert, gibt es für Java fertige Lösungen die relativ einfach integriert werden können. Der Nachteil ist suboptimaler Code der viel Speicher verbraucht. Allerdings sollte man einen großen Nachteil von C++ Templates nicht verschweigen, wenn man nicht aufpaßt kommt da zwar immer noch hoch optimierter Code heraus, aber die Compilezeit wächst astronomisch.



  • ~john schrieb:

    Allerdings sollte man einen großen Nachteil von C++ Templates nicht verschweigen, wenn man nicht aufpaßt kommt da zwar immer noch hoch optimierter Code heraus, aber die Compilezeit wächst astronomisch.

    Anderseits erlauben Generics & Co nicht mal Ansatzweise das, was C++ Templates erlauben. Ich gebe dir aber recht, das man das Argument der Compilezeit nicht ganz übersehen darf, wobei dem Kunden eher die Laufzeit interessiert (Aus Programmierersicht mag es wieder anders aussehen ;p).



  • tfa schrieb:

    Was passiert, wenn ich ein Objekt anlege und es in z.B. eine Liste/Hashtabelle o.ä. einfüge und erst Stunden später wieder lösche? Das ist doch dann auch Handarbeit. Ein GC ist da schon mächtiger.

    Nein, mit einem GC hat man exakt das gleiche Problem. Man muß sich immer Gedanken darüber machen, wie die Lebenszeit eines Objekt aussehen soll. Wenn ich in einer Liste ein Objekt referenziere, dann bleibt dies unabhängig von Reference Counting oder GC am Leben und wird nicht abgeräumt. Viele Programmierer machen sich bei Sprachen mit eingebautem GC nicht mehr die Mühe, über die Lebensdauer von Objekten nachzudenken, so daß hier Resourcenlecks entstehen.

    Nur bei zirkulären Strukturen hat ein GC echte Vorteile. Ansonsten kommt es darauf an, welchen konkreten Code man sich anschaut. Manchmal ist RC schneller manchmal GC, das kommt auf den Kontext an.



  • Was habt ihr eigentlich die ganze Zeit mit dem Garbage Collector? Wem sowas in C++ fehlt, der soll sich den dazulinken und gut! Immerhin kann ich mir da aussuchen ob ich einen will oder nicht.



  • die sprache java ist langsam weil sie nur interpretiert wird. das muss hier auch mal gesagt werden. die reihenfolge ist so: asm -> c -> c++ -> java -> visual basic. das muss einem anfänger auch klar sein...



  • Eine Sprache kann nicht langsam oder schneller als eine andere sein. Begreift das endlich.



  • Was haben C++ Entwickler eigentlich mit ihren Templates? Ich finde sie absolut sinnlos. So wie ich das sehe sind Templates fuer 2 Sachen gut, zum einen als Typplatzhalter und zum anderen um den Compiler als Taschenrechner zu misbrauchen. Die Rolle der Typplatzhalter ist in einer stark typesierten Sprache irgendwie seltsam und um etwas auszurechnen brauche ich den Compiler nicht.

    Wieso forciert der Compiler die Typen so strikt, const-correctness, dynamic_cast und static_cast anstelle von (int)x und (foo*)x, printf() ist boese, usw. Aber auf der anderen Seite kann ich einer Funktion template <class T> T max(T a, T b) {} alles moegliche uebergeben, eine String-Klasse, eine Hashmap, int, float, char. Klar beschwert sich der Compiler nach 10min uebersetzen, dass das Interface falsch ist und liefert mir eine 10 Zeilen lange Fehlermeldung. Aber wieso kann man dann nicht gleich den Typen eingrenzen?



  • Nun als Hobbyprogrammierer, der mit C# angefangen und nun hauptsächlich mit C++ weitergemacht hat will ich mal aus meiner bescheidenen Erfahrung sprechen:
    1. Immer wenn jemand als Vorteil von C++ gegenüber C# oder Java den Performancevorteil nennt will ich gegen die Wand springen.. Das mag für manche Projekte zutreffen, aber für die breite Masse nicht. Wenn ihr euch ständig Gedanken über die Performance macht geht doch Maschienencode schreiben.
    2. Das was mir an C++ gefällt ist, dass so viele Dinge erlaubt werden. Ich habe dadurch auch viele Dinge gelernt und meinen Horizont in Richtung objektorientierter bzw. multiparadigmischer Sprachen stark erweitert. Viele Dinge, die z.B. oft geraten werden erscheinen aber perfektionistisch(auch wenn es die Syntax nicht ist) und in der Praxis zahlt es sich oft nicht aus. Ich denke auch, dass das größte Problem von C++ der Mangel an einheitlichen guten Bibliotheken ist(Die Standardbibliothek und Boost haben zwar eine sehr gute Qualtität, aber wie siehts mit GUI aus? Da gibts nix.) und man braucht oft ein wenig mehr Code um das selbe zu erreichen, weswegen Javaprojekte wohl schneller fertig werden.
    3. Der Grund warum ich hauptsächlich C++ benutze ist, das meine Projekte zwar keine Spiele sind, aber meistens etwas damit zu tun haben und da kommt für mich Java eigtl. weniger in Frage. XNA kann man unter Linux vergessen, also -> C++

    Aus Programmierersicht mag es wieder anders aussehen ;p

    http://xkcd.com/303/



  • DEvent schrieb:

    Was haben C++ Entwickler eigentlich mit ihren Templates? Ich finde sie absolut sinnlos.

    Das sagt jetzt viel über Dich und wenig über Templates aus. Aber wie wäre es mit Ada? Es gibt in Ada ebenfalls Generics, dafür in einer weniger verwirrenden Syntax.

    DEvent schrieb:

    Aber wieso kann man dann nicht gleich den Typen eingrenzen?

    Das ist ein altes bekanntes Problem von C++ Templates, und die dabei auftretenden Fehlermeldungen sind zu Recht berüchtigt. Deshalb wird die nächste ISO Norm eine Lösung beinhalten, die es erlaubt gleich Fehlermeldungen bei Übergabe eines ungeeigneten Typs auszugeben.



  • DEvent schrieb:

    Was haben C++ Entwickler eigentlich mit ihren Templates? Ich finde sie absolut sinnlos. So wie ich das sehe sind Templates fuer 2 Sachen gut, zum einen als Typplatzhalter und zum anderen um den Compiler als Taschenrechner zu misbrauchen. Die Rolle der Typplatzhalter ist in einer stark typesierten Sprache irgendwie seltsam...

    Das ist auch die Ansicht von vielen, die C++ nur an der Oberfläche kennen, oder nur aus der Anfangszeit der Templates. Und Typplatzhalter machen gerade in einer stark typisierten Sprache Sinn, um Typsichere Container etc. verwenden zu können und Code besser wiederverwerten zu können.

    Was können C++ Templates aber noch, was über reine Typersetzungen hinaus geht?
    a) Allgemeine Behandlungen mit der gleichen Syntax wiederverwerten, obwohl die Typen gänzlich unterschiedlich sind (z.B. Value/Pointer/Referenz); Thema: Templatespezialisierung
    b) Verhalten mit Änderung eines Parameters den Umständen anpassen (z.B. Smartpointer die sich über einen Templateparameter so umschalten lassen das Beispielsweise statt new/delete das COM-Modell [mit Release usw.] unterstützt wird) und dennoch sonst die gleiche Syntax erlauben (Der Smartpointer verhält sich nach außen genau so wie er es mit new/delete gemacht hätte); Thema: Policy-Klassen
    c) Verhalten bei Vererbung in Abhängigkeit der abgeleiteten Klasse umsetzen; Thema: curiously recurring template pattern
    d) Mittels oben genannten Punkten und der von dir belächelten Templatemetaprogrammierung können Dinge wie generische Funktionszeiger umgesetzt werden, unabhängig davon ob die "Funktion" in Realität eine freie Funktion, Klassenmethode oder gar ein Funktionsobjekt ist...

    Und vieles mehr.

    DEvent schrieb:

    Wieso forciert der Compiler die Typen so strikt, const-correctness, dynamic_cast und static_cast anstelle von (int)x und (foo*)x, printf() ist boese, usw. Aber auf der anderen Seite kann ich einer Funktion template <class T> T max(T a, T b) {} alles moegliche uebergeben,...

    Thema: Typsicherheit. Den im Gegensatz zu den dir genannten C-Casts wird bei Templates der Typ geprüft. Was tatsächlich ein Problem ist, sind die kryptischen Fehlermeldungen, die aber scheinbar nach und nach besser werden (wobei es noch ein langer Weg ist, bis diese auch für einen verständlich sind, der Templates nur am rande verwendet).

    Und was die Compilezeit angeht: Wir verwenden Templates in unserer Anwendung, und ja, es hat etwas die Compilezeit erhöht, aber bei weiten nicht in den Ausmaßen die du hier annimmst. Dies sieht in Projekten mit intensiver Nutzung der Templatemetaprogrammierung sicher anders aus, aber in einen 0815 Durchschnittsprojekt sind die Compilezeiten nicht so hoch als das man wirklich lange Kaffeepausen machen könnte. 😉

    Zudem sollte man Projekte eh ab einer gewissen Größe modularisieren.

    cu André



  • Auch PCHs (Precompiled Headers) können die intensive und komplexe Templates drastisch in der Compilezeit reduzieren. PCH muß man natürlich auch explizit einschalten, wird wahrscheinlich auch wieder ein Contra-Argument der hiesigen Java-/C#-Fraktion sein, weil man ja wieder einen COmpiler-Switch extra lernen muß.



  • HansiHinterseher schrieb:

    PCH muß man natürlich auch explizit einschalten, wird wahrscheinlich auch wieder ein Contra-Argument ... sein, weil man ja wieder einen COmpiler-Switch extra lernen muß.

    Und ist zudem Compilerabhängig. Sofern sich das nicht durch irgendwelche Änderungen an den Sourcen umsetzen lässt, okay. Aber wenn du (wie ich durchaus schon musste) mit mehreren Compilern paralell arbeitest, ist es ein Problem wenn diese die PCH unterschiedlich umsetzen, und die Sourcen ein Compilerabhängiges Include etc. benötigen.

    cu André



  • ~john schrieb:

    tfa schrieb:

    Was passiert, wenn ich ein Objekt anlege und es in z.B. eine Liste/Hashtabelle o.ä. einfüge und erst Stunden später wieder lösche? Das ist doch dann auch Handarbeit. Ein GC ist da schon mächtiger.

    Nein, mit einem GC hat man exakt das gleiche Problem. Man muß sich immer Gedanken darüber machen, wie die Lebenszeit eines Objekt aussehen soll.

    aber nur in seltenen ausnahmen. ein objekt, auf das es keinen verweis mehr gibt, oder objekte die sich gegenseitig referenzieren, aber auf keins davon mehr ein verweis im aktiven code besteht, schmeisst der GC irgendwann automatisch weg. funktioniert in 99% aller fälle wunderbar, ohne dass sich der programmierer darüber gedanken machen muss. und wenn dieses standard-verhalten mal nicht passt, bietet z.B. Java noch sogenannte weak-, soft- und phantom-references an.
    🙂



  • ~fricky schrieb:

    aber nur in seltenen ausnahmen. ein objekt, auf das es keinen verweis mehr gibt, oder objekte die sich gegenseitig referenzieren, aber auf keins davon mehr ein verweis im aktiven code besteht, schmeisst der GC irgendwann automatisch weg.

    Du hast den wichtigen Punkt übersehen "auf das es keinen verweis mehr gibt". Wenn diese Bedingung erfüllt ist, wir mit RC das Objekt ebenfalls abgeräumt. Die Ausnahme sind zyklische Strukturen, dann und nur dann hat ein GC einen echten Vorteil. Aber der ursprüngliche Einwand war, daß man mit RC irgend wo noch eine Referenz auf das Objekt hätte, und so es nicht zerstört würde. Exakt bei so einem Fall bietet der GC keinen Vorteil, da das Objekt nämlich immer noch referenziert wird, und er es ebenfalls nicht zerstören kann!



  • asc schrieb:

    Und ist zudem Compilerabhängig. Sofern sich das nicht durch irgendwelche Änderungen an den Sourcen umsetzen lässt, okay. Aber wenn du (wie ich durchaus schon musste) mit mehreren Compilern paralell arbeitest, ist es ein Problem wenn diese die PCH unterschiedlich umsetzen, und die Sourcen ein Compilerabhängiges Include etc. benötigen.

    Für gewöhnlich braucht man die PCHs nur während der Entwicklung. Wenn ich z.B. unter MSVC entwickle, habe ich meine PCHs eingeschaltet, da die Frequenz der Compile-Läufe sehr hoch ist.
    Andere Compiler (zum Testen) lasse ich für gewöhnlich seltener laufen, z.B. bevor ich meinen Code in die Sourceverwaltung einchecke. Und dieser Compile-Lauf darf dann etwas länger laufen. Bzw. wenn man es richtig machen will, hat man eine Build-Maschine stehen, die selbstständig die Builds für die Compiler laufen lässt. Da ist es mir während der Entwicklung unter MSVC egal wie lange die Builds auf der entfernten Maschine laufen, da ich selbst nicht drauf warten muß. Sind die Builds fehlerhaft, kann mich die Build-Maschine informieren (z.B. per EMail). Auch Runtime-Tests kann man automatisieren.

    Also weiß ich nicht was da wirklich das Problem ist. Keiner kann mir erzählen, das er alle Compiler während der aktiven Entwicklung testet. Weil das dauert mit oder ohne Templates generell zu lange.

    Wenn mehrere Leute in einem Projekte unterschiedliche Compiler zur aktiven Entwicklung benutzen, kann jeder für die PCH-inkludierung selber sorgen. Den MSVC stören ja GCC-PCHs nicht und umgekehrt.

    Die Buildtools wie BBv2 (bjam) unterstützt dagegen PCHs compilerneutral. Einmal in das Buildscript aktivieren, den Rest macht das BBv2.



  • HansiHinterseher schrieb:

    Wenn mehrere Leute in einem Projekte unterschiedliche Compiler zur aktiven Entwicklung benutzen, kann jeder für die PCH-inkludierung selber sorgen. Den MSVC stören ja GCC-PCHs nicht und umgekehrt.

    Ich habe die Compilerkonfiguration (beide älter als der C++ Standard...) nicht mehr im Zugriff, kann auch sein das jemand einfach Mist bei den Einstellungen gemacht hat (Anschließend mussten im anderen Compiler dummy-stdafx.h generiert werden usw.). Und ja, beide Compiler wurden paralell für das Projekt eingesetzt, unterschiedliche Module in dem einen, oder anderen, teilweise aber auch gleiche Codebasis...

    Ich muß dazu aber auch sagen, das ich selbst ohnehin kaum mit PCHs arbeite, da ich keine großen Compilezeiten habe (Ich verwende aber auch Techniken wie das Handle-Body Idiom und ähnliches was die Compilezeiten eh schon reduziert).

    cu André



  • asc schrieb:

    Thema: Typsicherheit. Den im Gegensatz zu den dir genannten C-Casts wird bei Templates der Typ geprüft. Was tatsächlich ein Problem ist, sind die kryptischen Fehlermeldungen, die aber scheinbar nach und nach besser werden (wobei es noch ein langer Weg ist, bis diese auch für einen verständlich sind, der Templates nur am rande verwendet).

    Du hast mich nicht verstanden. Bei

    template <class T>
    T GetMax (T a, T b) {
      T result;
      result = (a>b)? a : b;
      return (result);
    }
    

    wird kein Typ geprueft. T kann alles sein, der Compiler prueft nur, ob das Interface stimmt. Das ist ja fuer mich der Widerspruch zu dem restlichen Konzept von C++. Templates fuehren ein Konzept von z.B. JavaScript in C++ hinein. IMHO ist das dann die Ursache der kryptischen Fehlermeldungen. Der Compiler muss erst bin ins Letzte uebersetzen um am Ende zu merken dass das Interface nicht stimmt oder ein template Typ A nicht mit template Typ B uebereinstimmt, obwohl es so sein muesste.


Anmelden zum Antworten