struct Foo und typedef struct Foo_



  • naja, es gibt schon echt fiese konstruktionen, die ohne 'typedef' super-hässlich und unleserlich sind.

    In C gehts ja noch, aber in C++ wirds wegen Templates schon unuebersichtlich.



  • DEvent schrieb:

    naja, es gibt schon echt fiese konstruktionen, die ohne 'typedef' super-hässlich und unleserlich sind.

    In C gehts ja noch, aber in C++ wirds wegen Templates schon unuebersichtlich.

    mag sein, aber auf c++ kann man zum glück so gut wie immer verzichten.
    🙂



  • pointercrash() schrieb:

    Inwiefern sollen typedef und enum unverzichtbar sein?

    Unverzichtbar sicher nicht. Aber ein typedef ist u.a. sehr geschickt weil man manchmal halt eben die Implementierung hinter dem Typ verstecken will. Beispiel FILE . Man braucht überhaupt nicht zu wissen was sich dahinter verbirgt, struct, union, bitfield, int. Alles läuft über die gegebenen Schnittstellen (fopen, fclose, fwrite, ...) ab.



  • es ist doch ein essentieller Unterscheid, ob ich von C oder von C++ rede, oder nicht? Das eine ist eine prozedurale Programmiersprache aus den 70er Jahren, mit der ich absolut Speicher und CPU effizient Coden kann - damals hat man auch die Notwenigkeit dafür noch gehbat. Zu Zeiten von C++ und C#, was nunmal der Objektorientierung angehört wird kaum mehr Wert auf Ressourceneffizienz gelegt. Man kann allerdings objektorientiert viel schneller kompelxe Programme stricken, ohne sich Gedanken machen zu müssen, wie kopmlexe Datentypen intern aussehen, wie sie behandelt werden müssen usw.! Die Anforderungen haben sich also im Laufe der von Ressourcenknappheit auf der hardwareseite nach Zeitknappheit bei der Entwicklung verlagert - und daraus resultiert nun mal eine vereinfachte Benutzung der Programmiersprache bei der gleichen Aufgabenstellung.

    Und zu dem struct / enum oder typedef und nicht struct / enum: wenn man professionell programmiert und dabei auf eine gewisse Lesbarkeit und Wiederverwendbarkeit der eigenen Quelltexte achten muss kann man sicherlich auch die typedefs nicht allzu gut einsetzen, um dem "Wiederverwender" zu ermöglichen, den Quelltext sauber zu lesen ohne erst jedes Header-File studieren zu müssen. Wenn man allerdings privat codet und weiß, man wird nur selbst jemals den Quelltext zu Gesicht bekommen und man kann sich merken, wie man seine eigenen Datentypen, Strukturen, Enumerationen und so weiter definiert hat, dann kann man sie ja durchaus dem Compiler auch mit typedef bekannt geben.

    Soviel zu meiner Meinung zu dem Thema - ob sie nun einer wissen will oder nicht!



  • @ Tim:

    Das Problem dabei ist: FILE ist Well-Known und kann überall nachgeschaut werden. Wenn ich mir allerdings jetzt selbst eine Structur schreibe, die beispielsweise einen Mitarbeiter mit allen Attributen definiere sollte ich einem potenziellen Leser meines Codes schon die Möglichkeit geben, nach zu vollziehen, was ich tue und wie, oder meinst du nicht?



  • AnonymousCoder schrieb:

    es ist doch ein essentieller Unterscheid, ob ich von C oder von C++ rede, oder nicht?

    Wir sind hier im C-Unterforum, von daher ist klar worüber wir reden. Womit ich den weiteren Absatz (den du btw. nochmal überdenken solltest) nicht weiter kommentieren werde.

    AnonymousCoder schrieb:

    Und zu dem struct / enum oder typedef und nicht struct / enum: wenn man professionell programmiert und dabei auf eine gewisse Lesbarkeit und Wiederverwendbarkeit der eigenen Quelltexte achten muss kann man sicherlich auch die typedefs nicht allzu gut einsetzen, um dem "Wiederverwender" zu ermöglichen, den Quelltext sauber zu lesen ohne erst jedes Header-File studieren zu müssen.

    Bezüglich der Lesbarkeit: Das ist im Zweifelsfall eine Meinungssache und hat mit "professioneller Programmierung" erstmal nichts zu tun. Aber wenn du Header-Files lesen musst, um einen Typen genauer zu identifizieren (Struktur, Enumeration, plain int, ...) dann fehlt dem Projekt zumindest ein Aspekt der "professionellen Programmierung", nämlich eine ordentliche Doku. Und in der musst du so oder so nachschauen, wenn du wissen willst was ein Typ T genau ausmacht (welche Member, welche Konstanten kennt das enum, ...), egal ob du nun schon weisst dass es ein struct oder ein enum oder sonstwas ist.

    Bezüglich der Wiederverwendbarkeit: Du schreibst ein Modul welches andere Entwickler benutzen müssen. Denken wir an ein theoretisches Objekt (z.B. etwas wie ein FILE) mit dem die Leute arbeiten. Wir nennen es struct obj , mit dem Konstruktor struct obj *obj_init(void) , dem Destruktor void obj_kill(struct obj *object) und ein paar anderen Methoden wie z.B. void obj_send_data(struct obj *object, int data) . Nun kann es im Laufe der Entwicklung passieren, dass sich deine Implementierung ändert, so merkst du (aus welchen Gründen auch immer) dass die Implementierung als struct obj Nachteile hat und willst nur noch eine ID (vom Typ int z.B.) in der Schnittstelle verwenden. Natürlich musst du nun alle deine Funktionen anpassen, aber viel schlimmer noch, die Benutzer deines Moduls müssen es ebenfalls. Hättest du von Anfang an ein typedef struct obj obj_t benutzt, könntest du jetzt einfach ein typedef int obj_t machen und die Schnittstelle hat sich nicht geändert.



  • AnonymousCoder schrieb:

    es ist doch ein essentieller Unterscheid, ob ich von C oder von C++ rede, oder nicht? Das eine ist eine prozedurale Programmiersprache aus den 70er Jahren, mit der ich absolut Speicher und CPU effizient Coden kann - damals hat man auch die Notwenigkeit dafür noch gehbat.

    glaubst du wirklich, dass diese notwendigkeit heute nicht mehr besteht?
    C ist zwar ein steinalter hund, aber auf dem gebiet der hardwarenahen system- und low-level programmierung auch heute noch unersetzlich.
    🙂



  • AnonymousCoder schrieb:

    @ Tim:

    Das Problem dabei ist: FILE ist Well-Known und kann überall nachgeschaut werden. Wenn ich mir allerdings jetzt selbst eine Structur schreibe, die beispielsweise einen Mitarbeiter mit allen Attributen definiere sollte ich einem potenziellen Leser meines Codes schon die Möglichkeit geben, nach zu vollziehen, was ich tue und wie, oder meinst du nicht?

    Wieso sollte es bei einem FILE anderes sein als mein eigenes Object FOO?

    Ich weis z.B. absolut nicht was sich hinter FILE versteckt, interessiert mich auch nicht im geringstem. Ich weis nur das ich es braucht fuer fopen(), fclose() usw. und wenn ich irgendwann eine foo(FILE* file) habe, dann gehe ich davon aus das derjenige der foo() implementiert hat, genau weis wie man FILE benutzt.

    Aber schoen das man mir die Frage beantwortet hat ob man

    struct Foo {} 
    // oder
    typedef struct _Foo {} Foo;
    

    schreiben soll. Werd bei naechster Gelegenheit meine Programme auf letzeres umstellen.

    Uebrigens programmiere ich in C (fast) genauso Objectorientiert wie in Java/C++. Mir fehlt da nur dass man keine privaten Attribute in C hat, bzw. ich weis nicht wie man private Attribute am besten implementieren kann.



  • DEvent schrieb:

    Uebrigens programmiere ich in C (fast) genauso Objectorientiert wie in Java/C++.

    immer? wofür benutzt du denn C?

    DEvent schrieb:

    Mir fehlt da nur dass man keine privaten Attribute in C hat, bzw. ich weis nicht wie man private Attribute am besten implementieren kann.

    naja, access levels wie z.b. in Java sind ja eigentlich nur in zusammenhang mit vererbung wichtig. in deinen C-objekten könntest du objektinterne attribute verstecken, indem du erst gar keine funktionen bereitstellst, die diese members direkt verändern.
    🙂



  • DEvent schrieb:

    Mir fehlt da nur dass man keine privaten Attribute in C hat, bzw. ich weis nicht wie man private Attribute am besten implementieren kann.

    selbst das hab ich schon mal gesehen (bei gtk)

    In KlasseEins.h. Die einzige Datei die für die Benutzer der Bibliothek öffentlich ist.

    /* KlasseEins.h */
    
    struct c_KlasseEins {
      /* private Attribute */
      void *privat;
    
      /* öffentlich Attribute */
      int x;
      int y;
      ...
    };
    
    typedef struct c_KlasseEins KlasseEin;
    

    In KlasseEin.c

    /* KlasseEins.c */
    
    #include <mylib/KlasseEins.h>
    
    struct c_KlasseEins_privat {
      int privat_attrib1;
      double privat_attrib2;
      ...
    };
    
    typedef struct c_KlasseEins_privat KlasseEins_privat;
    
    /* Konstruktor */
    KlasseEins *init_KlasseEins(...)
    {
        KlasseEins *tmp;
        KlasseEins_privat *privat;
    
        tmp = malloc(sizeof(*tmp));
    
        if(tmp == NULL) return NULL;
    
        privat = malloc(sizeof(*privat));
    
        if(privat == NULL)
        {
            free(tmp);
            return NULL;
        }
    
        /* öffentliche Attribute initialisieren */
       tmp->...
    
       /* private Attribute initialisieren */
    
       privat->...;
    
       tmp->privat = privat;
    
       return tmp;
    }
    
    int KlasseEins_tutirgendwas(KlasseEins *K)
    {
        KlasseEins_privat *privtat;
    
        if(K == NULL) return 0;
    
        /* auf private Attribute zugreifen */
        privat = K->privat;
        ...
    }
    

    Da KlasseEins_privat nur in der C Datei definiert ist, weiß der Bentutzer der Bibliothek (der KlasseEins.h includiert) gar nicht wie 'KlasseEins->privat' aussieht und somit werden diese Attribute privat. Das ist sogar mit Vererbung kompatibel.



  • OOP-freak schrieb:

    DEvent schrieb:

    Uebrigens programmiere ich in C (fast) genauso Objectorientiert wie in Java/C++.

    immer? wofür benutzt du denn C?

    Wieso soll ich die Vorteile hardwarenaher Programmierung und OOP nicht kombinieren?

    @supertux danke 🙂



  • DEvent schrieb:

    OOP-freak schrieb:

    DEvent schrieb:

    Uebrigens programmiere ich in C (fast) genauso Objectorientiert wie in Java/C++.

    immer? wofür benutzt du denn C?

    Wieso soll ich die Vorteile hardwarenaher Programmierung und OOP nicht kombinieren?

    weil OOP nicht immer was bringt. manchmal ist es einfach nur sinnloser ballast.
    🙂


Anmelden zum Antworten