Eure Programmierkonventionen ?



  • @ Marc++us : OK! Es gibt Stellen, an denen Kommentare überflüssig sind. Wenn die Parameternamen aussagekräftig genug sind, dann reicht das oft. Wenn eine Methode allgemeiner gehalten (bzw. abstrakter) gehalten ist, dann reicht es IMHO meistens nicht. Meistens kommentiere ich ja auch nicht (Hast du meinen ersten Satz überlesen?).

    Natürlich kann ich als Code-Fremder mit deinem Code so nichts anfangen. Mir ist z.B. nicht klar, warum kein bool zurückgegeben wird. Auch die Parameter sagen mir natürlich recht wenig. Was mich interessieren würde, wäre, wann z.B. die Exception eworfen wird.

    Hier jetzt mal eine Klasse aus meinem aktuellen Java-Projekt. Denkst du nicht, dass die ein paar Kommentare nötig hätte?

    [java]
    package image.pixelConverter;

    import image.*;

    public class HueConverter implements PixelConverter
    {
    public HueConverter ()
    {
    }

    public float convert (int rgbValue)
    {
    double red = ((double)(((int)rgbValue >> 16) & 0x000000ff))/255.0;
    double green = ((double)(((int)rgbValue >> 😎 & 0x000000ff))/255.0;
    double blue = ((double)(rgbValue & 0x000000ff))/255.0;
    if ((red == green) && (red == blue)) return -1.0f;
    double hue = Math.acos (((red - 0.5*(green+blue))/
    Math.sqrt((red-green)(red-green)+(red-blue)(green-blue))));
    if (blue > green) hue = 2.0 * Math.PI - hue;
    return (float) hue;
    }

    public short convertNormalized (int rgbValue)
    {
    return (short)Math.round(convert (rgbValue) * 127.5 / Math.PI);
    }
    }[/code]



  • Kommentare im Code -> JA, in Form von Überschriften. Ich würde das nicht über den Funktionskopf schreiben.

    [java]
    public float convert (int rgbValue)
    {
    // RGB-Anteile ausmaskieren und auf 1 normieren
    double red = ((double)(((int)rgbValue >> 16) & 0x000000ff))/255.0;
    double green = ((double)(((int)rgbValue >> 😎 & 0x000000ff))/255.0;
    double blue = ((double)(rgbValue & 0x000000ff))/255.0;

    // Grauwerte erkennen
    if ((red == green) && (red == blue)) return -1.0f;

    // Farbwert aus spektralem Farbrad ermitteln
    double hue = Math.acos (((red - 0.5*(green+blue))/
    Math.sqrt((red-green)(red-green)+(red-blue)(green-blue))));
    if (blue > green) hue = 2.0 * Math.PI - hue;
    return (float) hue;
    }
    }[/code]

    Sorry - couldn't resist. 😉

    Aber die Forderung nach der Auskommentierung der Köpfe ist falsch. Das führt oft dazu, daß die Funktionsköpfe die einzigen Programmteile - umrahmt von vielen ****** und ------ - sind, die kommentiert wurden. Im Code dagegen sind keine Kommentare zu finden. Dabei sind sprechende Funktionsköpfe noch leichter zu finden als sprechende Algorithmen.



  • Naja! Vielleicht gibt es da auch Unterschiede zwischen Java und C++. Wenn ich in Java eine Methode benutzen möchte, dann gucke ich mir normalerweise die Javadoc-Dokumentation dazu an, nicht den Quellcode (es sei denn, es kommt sehr auf Performance an). Wenn es dann keine Kommentare über dem Methodenkopf gibt, dann fehlt mir in diesem Fall z.B. folgendes :

    1. rgbValue : Wie stecken da r,g,b eigentlich drin? Kann letztendlich auf alle möglichen Arten angeordnet sein. Kann auch sein, dass mit einem 16-Bit RGB-Wert gerechnet wird.

    2. Grauwerte : Was passiert mit denen überhaupt. Ohne Kommentare weiß man nicht, dass dann -1 zurückgegeben wird.

    3. Wertebereich des Rückgabewertes : Kann ohne Kommentare alles mögliche sein. Könnte auch auf einen Wert zwischen 0 und 1 normalisiert sein, oder auf einen Wert zwischen 0 und 255.



  • ...
    Und schon haben wir einen wunderschönen Flamewar 🙄



  • Original erstellt von Headhunter:
    ...
    Und schon haben wir einen wunderschönen Flamewar 🙄

    Aha? Meinst du mich und Marc++us? Gib mal ein Beispiel für geflame. Ich sehe keins.

    ...oder darf ich das Wort "Java" nicht mehr benutzen? Ich habe da ja noch nichtmal irgendeine Wertung abgegeben!



  • ich mach es eigentlich aehnlich wie Dimah 🙂

    aber:

    membervariablen nicht extra kennzeichne.

    als Laufvariablen nehme, wie es sich eingebuergert hat: i,j,k

    und pointer <-> referenzen: jedes zu seiner Zeit 😉

    meine Kommentare sind englisch und ich wuerde sagen ziemlich aehnlich wie Marc++us es vormacht 😉 ausserdem dokumentiere ich gerne mit doxygen.



  • Tabulatoren sind doof.

    Sicher das du das ernst meinst? Dann hast du nämlich keine Ahnung. Leerzeichen sind doof. :p



  • Also bei der Funktion isProcessFinished könnte man noch die Preconditions und wenn's gibt auch die Postconditions kommentieren 😕



  • Original erstellt von <Falsch>:
    Sicher das du das ernst meinst? Dann hast du nämlich keine Ahnung. Leerzeichen sind doof. :p

    Hast du dir schonmal Code mit Tabulatoren im Windows-Editor angeguckt? ...oder in einem anderen einfachen Editor? Ich möchte nicht für alles gleich ne IDE starten, trotzdem möchte ich, dass der Code überall lesbar ist (auch für Leute, die keine IDE haben, wo man die Tab-Größe einstellen kann).

    [ Dieser Beitrag wurde am 28.11.2002 um 21:38 Uhr von Gregor editiert. ]



  • Mein Testprojekt:

    //header
    
    #include <vector>
    
    namespace david {
    
    template <typename T, typename U, typename V, typenamw W, int INGROSZ>
    class Foo {
    //typedefs, classes, types halt
        typedef std::vector<std::vector<T> > NetterTyp;
    
    //Variablen
        int einSehrAussageKraeftigerNameDadurchLerntManSchnellSchreiben;
    
    //get/set    
        int getEinSehrAussageKraeftigerNameDadurchLerntManSchnellSchreiben () const;
        void setEinSehrAussageKraeftigerNameDadurchLerntManSchnellSchreiben (int ein SehrAussageKraeftigerNameDadurchLerntManVielSchreiben);
    
    //funktionen
        T start ();
        T stop ();
    
        T startSmoking ();
        T stopSmoking ();
    
        T doSmoking ();
        T resumeSmoking ();
        T pauseSmoking ();
    
        bool isSmoking () const;
        bool invertBool ();   //returns last value of Bool
    
        void run (); //nur void (void) mit run Präfix!
    
    /*
        Anmerkung: Ich nehme immer nur
        start, stop, do, resume, pause, end, is, invert, exec, run
        als Präfix für Memberfunktionen (oder als einziger Name, bei einer Klasse 
        "Applikation" z.B. ist ja dann logisch Application::run()
    */
    public:
    
        Foo (int einSehrAussageKraeftigerNameDadurchLerntManSchnellSchreiben = 0);
    };
    
    }
    //unit
    #include "header"
    /*namespace david {
       using namespace std;
    }*/ //Maybe...
    using namespace david;
    Foo::Foo (int einSehrAussageKraeftigerNameDadurchLerntManSchnellSchreibenAberWennDerNameZuLangIstKuerzeIchIhnNatuerlichAufJedenFallMitEinemUnterstrichDanach_) :
    einSehrAussageKraeftigerNameDadurchLerntManSchnellSchreiben(einSehrAussageKraeftigerNameDadurchLerntManSchnellSchreibenAberWennDerNameZuLangIstKuerzeIchIhnNatuerlichAufJedenFallMit EinemUnterStrichDanach_)
    {}
    
    //M$ VC++: #define for if(1)for
    
    template <typename T, ... >
    T
    Foo<T>::startSmoking () {
       for (int i = 0; i < 1000; ++i) {
         for (int j = 0; j < 1000; ++j) {
           for (int k = 0; k < 1000; ++k) {
              Sleep(10); //ahh Smoking...
           }
         }
       }
       stopSmoking ();
    }
    
    template ...
    T
    Foo::stopSmoking () {
       while (true) {
          cout << "No!" << endl;
          resumeSmoking ();
       }
    }
    
    T
    Foo::resumeSmoking () {
        if (getEinAussageKraeftigerNameDadurchLerntManSchnellSchreiben() != INGROSZ) 
          cout << "Damned!" << endl;
          startSmoking ();
          return;
        pauseSmoking ();
        resumeSmoking ();
    }
    
    T
    Foo::pauseSmoking () {
        while (getEinAussageKraeftigerNameDadurchLerntManSchnellSchreiben() < INGROSZ) {
           cout << "I need more cigarettes!!!" << endl;
           setEinAussageKraeftigerNameDadurchLerntManSchnellSchreiben(getEinAussageKraeftigerNameDadurchLerntManSchnellSchreiben()+1);
        }
    }
    
    void
    Foo::run () { //Der Haupt Treiber
       start ();
       startSmoking ();
       stop ();
    }
    
    T
    Foo::start () {
       cout << "Welcome! Smoke?" << endl;
       string input;
       getString (input, isSetTo<string> ("Yes"), "Ungueltig! Nochmal eingeben: "); //eigene Nette kleine (template)Funktion
    }
    
    //main
    #include "header"
    
    int main () {
       Foo smokingApp;
       smokingApp.run ();
     //no need for return...
    }
    

    [ Dieser Beitrag wurde am 28.11.2002 um 21:06 Uhr von Noesis editiert. ]

    [ Dieser Beitrag wurde am 28.11.2002 um 21:07 Uhr von Noesis editiert. ]

    [ Dieser Beitrag wurde am 28.11.2002 um 21:08 Uhr von Noesis editiert. ]



  • wenn du das wirklich mit leerzeichen machst, hast du aber viel zu tun. 🙄



  • tabulatoren sind wirklich doof. kuck dir mal manche codes hier im forum an, die tabs enthalten. da springen immer irgnedwelche zeilen aus der reihe. genauso in word.
    weil fuer tabs gibts ueberall etwas andere einstellungen, leerzeichen(bei mir 4 pro tab) sind eindeutig.

    ansonsten

    class MyCoolClass{
        int myCoolAttribute_;
    };
    void myCoolFunc();
    int myCoolVar;
    

    ungarische notation ist der letzte unsinn.
    guter code braucht nur sehr selten kommentare, nur bei komplexen algorithmen oder irgendwelchen fiesen tricks.
    und natuerlich alles in englisch.

    dimah: was hat volkard gesagt, was dich zu fooBar statt fooBar_ bewegen wird?



  • Original erstellt von <fast>:
    wenn du das wirklich mit leerzeichen machst, hast du aber viel zu tun. 🙄

    Ich stelle natürlich meine IDE so ein, dass sie Tabs automatisch durch Leerzeichen ersetzt! 🙂 :p



  • im vs kann man spaces gleich oder nachtraeglich in tabs umwandeln lassen und umgekehrt.



  • wo geht das in visual studio? ich möchte alle meine quelltextdatei von tabs nach leerzeichen umstellen!



  • ich machs fast so wie dimah
    nur noch:

    eindeutige var und klassen namen (nicht z.B. int hanswurst)

    int test()
    { //<- die klammer unten und nicht oben
    }
    

    immer tabs

    if (x)
    {
        if (y)
        {
            if (z)
            {
                cout << "hallo";
            }
        }
    }
    

    lange funktions definitionen rechtzeitig "teilen"

    typdefs nur wenn umbedingt nötig, machen das programm teilweise schwer zum lesen

    in klassen:
    funktionen zum variablen setzen: setXXX()
    funktionen zum variablen lesen: getXXX()
    funktionen die bool returnen: isXXX()

    ein "richtiger" progger nimmt nicht den windows editor.



  • Original erstellt von <sigi>:
    **```cpp
    int test()
    { //<- die klammer unten und nicht oben
    }

    Weshalb eigentlich? Mir fallen mindestens 2 gute Gründe dagegen ein, und eine Begründung, wann doch...



  • so finde ich es übersichtlicher.
    welche gründe sprechen denn dagegen?



  • Original erstellt von Gregor:
    Hast du dir schonmal Code mit Tabulatoren im Windows-Editor angeguckt? ...oder in einem anderen einfachen Editor?

    Dann machs richtig:

    for (std::vector<int>::const_iterator it = v.begin (), et = v.end ();
    ^      it != et; ++it) {
    |  ^^^`---------------------------------\
    |   h (f (*it), g (*it)); i (*it);       |
    | }^                                     |
    |^ |                                     |
    Tabs                                     Leerzeichen
    

    Ich hatte mit meinen Codes noch nie Probleme sie mit irgendeinem Editor (ed bis kedit) zu bearbeiten. Das können Leute auch lesen, die lieber 1, 4 oder 8 Tabs breit lesen. Mit Leerzeichen zwingt man dem Leser hingegen seinen 'Programmierstil' auf.



  • Welche Gründe sprechen für Tabs?


Anmelden zum Antworten