C++ und wikipedia



  • Also ich sehe die änderungen, wie gesagt nur im Text selbst kann ich als unangemeldeter was ändern, die Option "umbenennen" gibt es bei mir nicht.



  • die heisst ja auch "verschieben" 🙄



  • Deshalb hab ich das umbenennen ja auch in "" geschrieben, weil es verschieben heißt, laut dir, aber wie gesagt das verschieben find ich nicht, wo steht das



  • In der Leiste wo du auch zwischen Diskussion, Versionen und Bearbeiten hin und her klicken kannst. Ist vielleicht wirklich nur da, wenn man angemeldet ist.



  • volkard schrieb:

    ok. für java braucht man keinen.

    Was hat das mit Java zu tun?
    Z.B. geringe Änderungen für verschiedene Kunden lassen sich
    sehr elegant mit einem Präprozessor lösen.

    Jockel



  • Da jeder Compiler und jedes OS so sein eigenes Süppchen kocht gibt es auch genug Situationen, wo der Präprozessor einfach notwendig ist:

    Verschiedene Betriebssysteme - verschiedne Schlaf-Funktionen:

    #if defined(WIN32) || defined(__WIN32__) || defined(__NT__)
      #define WIN32_LEAN_AND_MEAN
      #define __MS__WINDOWS__
      #include<windows.h>
    #elif defined(__OS2__) || defined(OS2) // 32Bit only
      #define INCL_DOS
      #include<os2.h>
      #define Sleep(a) DosSleep(a)
    #elif defined(__DOS__) || defined(DOS) // 32Bit only
      #include<dos.h>
     #define Sleep(a) sleep(a)
    #elif defined(__unix) // Linux, *BSD, Solaris, QNX, ...
      #include<unistd.h>
      #define Sleep(a) sleep((a)/1000)
    #else
      #error Unsupported OS
    #endif
    

    Verschiedene Compiler - verschiedene Inline-ASM-Implementierungen:

    #if defined(__GNUC__)
      #define CPUID(p1,p2,p3,p4,p5) \
        asm volatile("push %%ebx ; cpuid ; mov %%ebx, %%esi ; pop %%ebx" \
          : "=a"(p1), "=S"(p2), "=c"(p3), "=d"(p4) : "a"(p5));
      #define RDTSC(v1,v2) asm volatile("rdtsc" : "=a"(v1), "=d"(v2));
    #elif defined(__BORLANDC__) || defined(__DMC__)
      #define CPUID(p1,p2,p3,p4,p5) \
        asm { mov eax, p5 ; cpuid ; mov p1, eax ; \
        mov p2, ebx ; mov p3, ecx ; mov p4, edx }
      #define RDTSC(v1,v2) asm { rdtsc ; mov v1,eax ; mov v2,edx }
    #elif defined(__WATCOMC__)
      void RDTSC(int &v1, int &v2);
      #pragma aux RDTSC = \
        ".586" \
        "push eax" \
        "push edx" \
        "rdtsc" \
        "mov esi, [esp]" \
        "mov [esi], edx" \
        "mov esi, [esp+4]" \
        "mov [esi], eax"  \
        "add esp, 8"  \
        parm [eax] [edx] \
        modify [eax edx];
      void CPUID (int &eax, int &ebx, int &ecx, int &edx, int val);
      #pragma aux CPUID = \
        ".586" \
        "push eax" \
        "push ebx" \
        "push ecx" \
        "push edx" \
        "mov eax, esi" \
        "cpuid" \
        "mov esi, [esp]" \
        "mov [esi], edx" \
        "mov esi, [esp+4]" \
        "mov [esi], ecx" \
        "mov esi, [esp+8]" \
        "mov [esi], ebx" \
        "mov esi, [esp+12]" \
        "mov [esi], eax" \
        "add esp, 16" \
        parm [eax] [ebx] [ecx] [edx] [esi] \
        modify [esi eax ebx ecx edx];
    #else
      #error unsupported compiler.
    #endif
    

    ...



  • @mastercpp
    Die Notwendigkeit eines Präprozessors für Kompiler die echten
    Maschinencode erzeugen hat auch niemand in Frage gestellt.



  • mastercpp! Und warum benutzt du nicht einfach eine andere Library, sprich für jedes OS eine eigene Library? Dann braucht man nur die Lib-Dateien austauschen und gut ist. Ich sehe bisher keinen Grund macros zu benutzten. Dein Beispiel ist eines wie ich es nicht machen würde.



  • Artchi schrieb:

    mastercpp! Und warum benutzt du nicht einfach eine andere Library, sprich für jedes OS eine eigene Library? Dann braucht man nur die Lib-Dateien austauschen und gut ist.

    Das halte ich aber für Quatsch. Angenommen du willst einfach ein anderes
    Programm starten (Linux/Windows). Es ändert sich nur eine Zeile
    (exec, bzw. CreateProcess) und dafür soll man ne eigene Lib schreiben?



  • Optimizer schrieb:

    volkard schrieb:

    Optimizer schrieb:

    Also, wofür braucht man einen Präprozessor? Die Frage steht immer noch im Raum. 🙂

    willst du mich veralbern?

    Nein. Ich habe deine Frage, wie man obiges in Java löst, beantwortet. Der Ausgangspunkt war, dass anscheinend jemand in Java einen Präprozessor vermisst. Ich frage mich, wofür?

    sorry, also ich benutze (bzw. bin grad dabei es zu lernen 🤡 ) java um anwendungen für handys zu schreiben! Da man standardmäßig nicht auf LL auf die Hardware zugreifen kann, bracucht man für jeden handytyp / marke eine eigene API! um das prog nicht für alle typen portieren zu müssen, empfehlen alle den gebrauch eines präprozessors! wenn man sagt in java gäbe es einen, kann man genausogut sagen, in c++ gäbe es einen gb!



  • Wer in Java - oder welcher Sprache auch immer - einen Präprozessor brauch,
    der soll einen Nutzen. Wo ist eigentlich das Problem?
    Ob man das immer unbedingt muss sei mal dahin gestellt, aber häufig
    ist das schon ganz hilfreich.



  • Artchi schrieb:

    mastercpp! Und warum benutzt du nicht einfach eine andere Library, sprich für jedes OS eine eigene Library? Dann braucht man nur die Lib-Dateien austauschen und gut ist. Ich sehe bisher keinen Grund macros zu benutzten. Dein Beispiel ist eines wie ich es nicht machen würde.

    Dann nenn mir mal eine freie Library, die es für Windows, Linux, OS/2 2.x+ und 32-Bit DOS gibt und sich GCC, BCC und OpenWatcom compilieren lässt.



  • Jockelx schrieb:

    Wer in Java - oder welcher Sprache auch immer - einen Präprozessor brauch,
    der soll einen Nutzen. Wo ist eigentlich das Problem?
    Ob man das immer unbedingt muss sei mal dahin gestellt, aber häufig
    ist das schon ganz hilfreich.

    "Problem" und Ursache der Diskussion ist, dass in dem c++ Artikel gesagt wird, der Präprozessor in c++ sei nur ballast!



  • Na wenn in einem c++ Artikel gesagt wird, der Präprozessor sei in c++ nur Ballast, dann wird das wohl stimmen.
    Ich bleibe aber Rebell und nutze ihn weiter.

    Jockel



  • Ich sehe das so: Er ist da, fertig!
    Und bei Sprachen die keinen haben sehe ich das so: Er ist nicht da, fertig!

    mfg
    v R



  • Ich sehe das so: Er ist da, fertig!
    Und bei Sprachen die keinen (in der IDE integriert) haben sehe ich das so: Man nimmt einen seier Wahl, falls man ihn brauch.

    mfg
    Jockel



  • volkard schrieb:

    virtuell Realisticer schrieb:

    Warum geht ihr nicht hin und aendert den Text, indem ihr entsprechende Fehler
    korrigiert? Die Moeglichkeit ist gegeben.

    das glaube ich dir erst, wenn du es schaffst, den namen des spiels vom falschen "Nimm" aufs richtige "Nim" zu ändern.

    es klapt also nicht?
    ich sehe immernoch unter http://de.wikipedia.org/wiki/Nimm-Spiel den eintrag (allerdings lobenswerterweise im text Nim statt Nimm). und unter http://de.wikipedia.org/wiki/Nim-Spiel sehe ich nix.

    falls es argumentationshilfe braucht:
    ich schreib mal auf, was ich auswendig weiß, vielleicht sind gute google-worte dabei.
    nim gibt es in zwei regeln.
    (A) "wer den letzten nimmt, verliert"
    und
    (B) "wer den letzten nimmt, gewinnt".

    für B ist die strategie zu leicht durchschaubar:
    man verliert bei zwei gleichen stapeln (zum beispiel (4,4)). macht der andere daraus was ungleiches daraus (zum beispiel (4,2)), zieht man einfach nach (2,2). das geht so lange, bis (0,0) erreicht ist.
    entsprechenes gilt für jede beliebige stellung mit paarweise gleichen stapeln (2,2,6,6,4,4,3,3 oder 1,6,4,6,1,4).
    allgemein sind stellungen gewinnstellungen, wenn die einzelnen steinanzahlen der stapen mit XOR verknüpft 0 ergeben. test: 1 XOR 6 XOR 4 XOR 6 XOR 1 XOR 4 == 0. jo.
    es gibt nach der XOR-formel aber noch mehr gewinnstellungen, als nur welche mit gleichen stapelanzahlen. die kleinste abweichende ist 1,2,3.
    man kann leicht einsehen, daß sie gewinnt. nimmt der gegner die 1, macht man 2,2, draus. nimmt er irgendwas von der 2 oder 3, kann man auch zwei gleich große stapel erzeugen.
    die XOR-formel beschreibt ausnahmslos alle gewinnstellungen.

    wer spielt überhaupt nim? normalerweise führt man auf betrinknissen ein, wenn den leuten langweilig wird und man von den leuten weiß, daß sie gerne streichholzrätsel lösen (zum beispiel, wenn ihnen die streichholzrätsel ausgegangen sind). deswegen führt man auch lieber nim mit regel (A) ein.

    die strategie für A ist leicht anders: solange mindestens ein stapel mehr als ein streichholz (oben waren es noch steine, aber streichhölzer sind praxisnäher) hat, ist eine gewinnstellung aus (B) auch eine aus (A). anderenfalls ist eine gewinnstellung eine mit ungerader stapelanzahl (wobei jeder stapel genau ein streichholz hat).
    1,2,3 ist also auch gewinnstellung. verkürzt der gegner zu 2,3 oder 1,2,2 dann verkürzt man auf 2,2. verkürzt er aber auf 1,2,1, muß man auf 1,1,1 gehen (nicht 1,1 wie in (B)).

    eine abwandlung von nim ist unter dem namen "siebensprossige leiter" bekannt:
    man legt mit streichhölzern eine leiter mit 7 sprossen aus.

    | | | | | | |
    

    in jeden außer dem ersten zwischenraum legt man eine münze.

    |o|o|o|o|o|o|
    

    und beschreibt eine zugrichtung dergestalt, daß der anfangs leere zwischenraum
    ler letze in zugrichtung ist.

    |o|o|o|o|o|o|
       <--
    

    nun ziehen beide spieler abwechselnd, indem sie eine münze beliebig weit
    (aber mindestens über eine sprosse) in zugrichtung verschieben.
    wer nix mehr verschieben kann, hat verloren.
    es ist nur eine andere darstellungt für nim in version (B) und der anfangsstellung 1,2,3,4,5,6.

    aus den gründen, die zur vorliebe von (A) führen, ist die siebensprossige
    leiter natürlich auch eher nicht gefragt, man sieht zu leicht das system.

    die anfangsstellung ist an sich beliebig, aber zwei feste anfangsstellungen haben eine herausragende stellung:
    die heidelberger version und die marienbader version.
    die heidelberger versionb startet mit 1,2,3,4,5.
    die marienbader starte mirt 1,3,5,7.

    aus den gründen, die zur vorliebe von (A) führen, müßte die heidelberger version beliebter sein.
    dort ist die anfangsstellung keine siegstellng. man kann dem gegner immer überlassen, ob er anfangen will, oder nicht und wenn er anfängt, und eine siegstellng (aus versehen herbeiführt), verkürzt man möglichst auf was nicht offensichtliches (also 1,2,3,4,5 -> 1,2,2,4,5 -> 1,2,2,4,3! er müßte 1,2,2,2,3 finden. schlechter ist 1,2,3,4,5 -> 1,2,2,4,5 -> 1,2,2,4,4, weil er zu schnell 2,2,4,4 (und generell stapelpaarige stellungen) erkennt).

    der vollständige regelsatz, wenn man nicht immer XOR rechnen will für die heidelberger version in (B) (für A ist die abwandlung bekannt):
    zwei gleiche stapel gewinnen.
    1,2,3 gewinnt.
    1,4,5 gewinnt.
    2,3,4,5 gewinnt.
    zwei gewinnstellungen zusammen gewinnen (also 1,1,2,2 oder 1,2,2,4,5).

    nennenswert ist eine abwandlung namens kayles. in keyles darf man auf einem stapel nur 1 oder 2 hölzer nehmen, aber man kann auch mitten aus einem stapel herausnehmen, wodurch der stapel in zwei neue stapel geteilt wird. also aus 1,2,3,4,5 kann ich durch herausnehmen des mittleren holzes der 5 die stellung 1,2,3,4,2,2 erzeugen.

    nim wude vor allem durch filme bekannt. afair sind die marienbader und die heidelberger version durch je einen (sogar namensgebenden) film bekannt geworden. aber an die namen kann ich mich wirklich nicht erinnern. "liebe in marienbad" und "es war einmal in heidelberg" oder sowas.

    außerdem ist meine bemerkung "mit zwei "m"" auf
    http://www.volkard.de/vcppkold/nimmspiel.html bereits 1999 nur dem umstand entwachsen, daß ich nicht wollte, daß man das nimm-spiel mit dem nim-spiel verwechselt.



  • Optimizer schrieb:

    Also, wofür braucht man einen Präprozessor? Die Frage steht immer noch im Raum. 🙂

    uU für Versioning, oder Debugzwecke?

    Mit Debug meine ich mehr als assert. Ich meine damit zB ein und ausschaltbares logging oder auch DBC.

    Also: einen Präprozessor kann man schon verwenden und er ist hilfreich. Aber man kommt auch ohne aus. Dennoch ist er für mich klar ein Vorteil.

    Der Nachteil von C++ in bezug auf den PP ist #include - da ist ein Java import einfach besser und schöner.



  • Nur kurze Anmerkung:

    import ist mit #include eigentlich nicht vergleichbar sondern hat schlichtweg die selbe Funktion wie using. Includen muss man in Java schlichtweg nicht.

    Für Unterscheidungen zwischen Debug und Release kann man in Java eigentlich wunderbar if verwenden. Der HotSpot Optimierer stellt nach einiger Zeit fest, dass die Prüfung redundant ist und recompiliert das entsprechend. Er merkt sogar, wenn sich die variable ändert und compiliert dann den ganzen Teil neu.

    Aber gut, jeder wie er mag. 🙂
    Meine persönliche Meinung ist halt, dass es schöner ist, wenn ich in einer .class File sowohl die release als auch die debug Version in einem habe. Der JIT-Compiler soll dann entsprechend erst unterscheiden (debug-Variable, assert).
    Ich sehe aber auch kein Problem darin, einen PräPro zu nutzen, wenn das jemand lieber mag. Nur eine Notwendigkeit sehe ich nicht.



  • Optimizer schrieb:

    Für Unterscheidungen zwischen Debug und Release kann man in Java eigentlich wunderbar if verwenden.

    In C++ auch - es ist aber unschön weil der Unterschied Compiletime if und Runtime if nicht gegeben ist.

    Meine persönliche Meinung ist halt, dass es schöner ist, wenn ich in einer .class File sowohl die release als auch die debug Version in einem habe.

    Klar, aber dazu ist das C++ Modell leider unfähig. Liegt aber nicht am PP.

    Ich sehe aber auch kein Problem darin, einen PräPro zu nutzen, wenn das jemand lieber mag. Nur eine Notwendigkeit sehe ich nicht.

    Ich sagte ja, man kann ohne auskommen. Aber Sinn hat er trotzdem.


Anmelden zum Antworten