Dann steht eine bessere Lösung direkt unter dem Satz, den Du gequotet hast ^^Dirty Oerti hat geschrieben:Was ist aber, wenn du C schreiben MUSST ?Xin hat geschrieben: Wozu gibt es in C++ new?
Casten mit Carsten
- Xin
- nur zu Besuch hier
- Beiträge: 8862
- Registriert: Fr Jul 04, 2008 11:10 pm
- Wohnort: /home/xin
- Kontaktdaten:
Re: Ausdrücke in C
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
- Dirty Oerti
- Beiträge: 2229
- Registriert: Di Jul 08, 2008 5:05 pm
- Wohnort: Thurndorf / Würzburg
Re: C:Ausdrücke
Hups^^
Habe ich übersehen.
Habe ich übersehen.

Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne!
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.
Ich helfe gerne!

----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.
- fat-lobyte
- Beiträge: 1398
- Registriert: Sa Jul 05, 2008 12:23 pm
- Wohnort: ::1
- Kontaktdaten:
Re: Ausdrücke in C
Das ist für mich eine Krücke. Eine Krücke um etwas zu umgehen, was Teil der Sprache ist und das mir den genau den gleichen Effekt liefert empfinde ich als schlicht und einfach "überflüssig".Xin hat geschrieben:Code: Alles auswählen
union IntegerPointer { void * MemoryHandling; int * IntegerArray; }; union IntegerPointer intP; intP.MemoryHandling = malloc( ARRAYSIZE * sizeof( int ) ); intP.IntegerArray[0] = 1;
Deine lösung ist keinen deut Typsicherer. Ich kann zwar nicht IntegerPointer casten, aber ich kann sehr wohl IntegerPointer.IntegerArray casten, was genau das gleiche ist wie ein normaler Zeiger. Ich sehe hier keinen VorteilXin hat geschrieben:Mit dem Cast darf man integer_array auch mal nach (char *) konvertieren und auf einen String zeigen lassen. union IntegerPointer lässt das nicht zu.
Die implementierung möchte ich sehn, die ohne Casts auskommt. Wie willst du z.B. ein long und ein short zusammenhängend als Array Speichern? Entweder du Castest einen Zeiger auf dein char- array zu einem int, oder du nimmst nen Zeiger auf deine ints und castest diese nach char*. Nur weil du es in eine Klasse Kapselst, ist das Problem noch lange nicht weg.Xin hat geschrieben:C++ Lösung: Klasse erstellen, bestehend aus eigenen Longs, die sich als char-Array zurückgeben lassen.
Ich sehe hier keinen Unterschied zu meiner Version, es sind genausoviele Casts drinnen, wie bei mir, nur sind sie schon wieder in Funktionen versteckt. Ich brauche nicht für eine Funktion, die mir mal shcnell nen Paketheader zusammenbauen soll 2-3 unterfunktionen! Das ist alles Laufzeit, denn C89 hat keine inline- funktionen, das bedeutet im endeffekt (im assembly- pseudocode)Xin hat geschrieben:C Lösung: Funktionen verwenden, die klare Aussagen treffen, was sie tun. Hier könnte man sich wieder mit Unions behelfen, aber hier würde ich Casting akzeptieren, wenn es nur in den passenden Funktionen stattfinden würde
Code: Alles auswählen
WriteUnsignedint( char ** buffer, unsigned int l ) { *((unsigned int *) *buffer) = l; *buffer += sizeof( long ); } WriteUnsignedShort( char ** buffer, unsigned short s ) { *((unsigned int *) *buffer) = s; *buffer += sizeof( short ); } ... unsigned char buffer[BUFSIZE]; unsigned char ** bufferPos = &buffer;. WriteUnsignedLong( bufferPos, packed_length ); WriteUnsignedShort( bufferPos, header_length );
Code: Alles auswählen
; auf der aufruferseite:
push l
push buffer
call WriteUnsignedint
; auf der funktionsseite
push ebp
mov ebp, esp
pusha
...
popa
pop ebp
ret
; und wieder zurück:
pop eax
pop eax
Xin hat geschrieben:Grober Designfehler...
Code: Alles auswählen
struct Base { bool is_A; virtual void boringFunction() = 0; Base(bool _is_A) : is_A(_is_A) {} virtual void handler() = 0; }; struct DerivedA : public Base // <- gehe ich mal von aus... { DerivedA() : Base(true) {} virtual void boringFunction() {} void wickedFunction() {} void handler() { wickedFunction(); } } struct DerivedB : public Base { DerivedB() : Base(false) {} virtual void boringFunction() {} void coolFunction() {} void handler() { coolFunction(); } }
Pseodocode, oder einfache Beispiele drücken meist nicht das aus, was gemeint ist. In "Real World" Situationen gibt es nur sehr sehr selten perfekte Designs, oft sind verschiedene Design Patterns zusammengemischt und sind nur mit Kompromissen zueinander Kompatibel.
In diesem Fall ist "handler" keine globale Funktion, sondern eine callback Funktion von einer "Controller" Klasse, DerivedA und DerivedB sind Nachrichten, und werden von einer Klasse gesendet, die außer einem Funktionszeiger von der "Controller" Klasse nie etwas gesehen hat. Mag sein dass das design nicht Perfekt ist. Es ist aber ein guter Kompromiss, ich habe lange dran gefeilt (kannst Kerli fragen, wie ich ihn bei ICQ zugespammt habe

Das ganze ist ein Feature, dass man "Vererbung" nennt, und dazu gehören diese Casts noch dazu. Diese Technik wird auch in Bibliotheken verwendet, die nicht unter den 10 schlechtesten Libs sind, und zwar wxWidgets. Da gibts zum Beispiel die wxEvent Klasse, die die Basisklasse für viele andere Klassen ist.
Ich gebe dir Recht in dem Punkt, dass Casten in den meisten Fällen zu vermeiden ist. Ich gebe dir auch recht, dass casten ein Anzeichen eines Designfehlers ist, und auch dass man Generell casten vermeiden sollte.Xin hat geschrieben:Casten ist immer nur ein Armutszeugnis für einen Entwickler. In Beispiel 2 ist casten eine Vereinfachung, Lösung 1 würde hier auch greifen. Lösung 1 ist im letztendlich das gleiche wie Casten, aber es ist vorher klar, dass man nicht überall hinkonvertieren kann, sondern nur zu festgelegte Typen.
Casten in C++ ist ein Zeichen ist so gut wie überhaupt nicht mehr notwendig. Es gibt Fälle mit Templates, da komme ich nicht um Casten rum, um Redundanz zu vermeiden. Bevor ein Cast verwendet wird, sollte man lieber mal ein paar Tage in sich gehen und überlegen, was es für Alternativen gibt.
Nur Fakt ist: In echten Anwendungen, mit echten Bibltiotheken, echten Programmierern mit verschiedenen Programmierstilen ist es oft nicht zu vermeiden.
Auch finde ich es etwas ungerecht vom "Armutszeugnis" zu sprechen und Casten grundsätzlich zu verteufeln. Und zwar nicht nur aus dem Grund dass es tausende (hunderttausende?) Programmierer gibt, und Millionen von Codezeilen in denen Casts vorkommen. Eine Ansammlung von Bits sind Daten, die Interpretiert werden. Manchmal ist es notwendig und sinnvoll diese Daten anders zu interpretieren.
Ich meine, man darf einfach nicht generell Sprachfeatures verteufeln. Natürlich soll man Casts vermeiden, natürlich soll man keine goto's anwenden und auch so wenig wie möglich mit dem Präprozessor machen. Aber all diese sprachfeatures haben ihre Nischen, und müssen manchmal verwendet werden.
Haters gonna hate, potatoes gonna potate.
- Dirty Oerti
- Beiträge: 2229
- Registriert: Di Jul 08, 2008 5:05 pm
- Wohnort: Thurndorf / Würzburg
Re: C:Ausdrücke
Mal ne Frage zwischenrein:
Was genau ist an Casts schlecht?
Was genau ist an Casts schlecht?
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne!
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.
Ich helfe gerne!

----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.
- Xin
- nur zu Besuch hier
- Beiträge: 8862
- Registriert: Fr Jul 04, 2008 11:10 pm
- Wohnort: /home/xin
- Kontaktdaten:
Re: Ausdrücke in C
Hehehe, dann dürften Klassen für Dich auch eine Krücke sein.Der Effekt ist eben nicht der selbe, weil...fat-lobyte hat geschrieben:Das ist für mich eine Krücke. Eine Krücke um etwas zu umgehen, was Teil der Sprache ist und das mir den genau den gleichen Effekt liefert empfinde ich als schlicht und einfach "überflüssig".Xin hat geschrieben:Code: Alles auswählen
union IntegerPointer { void * MemoryHandling; int * IntegerArray; }; union IntegerPointer intP; intP.MemoryHandling = malloc( ARRAYSIZE * sizeof( int ) ); intP.IntegerArray[0] = 1;
Wenn Du nicht casten kannst, kannst Du auch IntegerPointer.IntegerArray nicht casten. Wenn eine Typumwandlung wie (typ) oder static_cast< typ >() verboten ist, ist da nix zu casten.fat-lobyte hat geschrieben:Deine lösung ist keinen deut Typsicherer. Ich kann zwar nicht IntegerPointer casten, aber ich kann sehr wohl IntegerPointer.IntegerArray casten, was genau das gleiche ist wie ein normaler Zeiger. Ich sehe hier keinen Vorteil
Wenn Du Verbote bewußt umgehst, darfst Du auch gleich *( (int *) 0 ) = 0; reinpacken. Das führt bewußt zum Absturz, aber wenn man sich nicht an Regeln hält und da das gültiger Code ist, ist das ja nicht das Problem des Entwicklers.
Du kannst wieder mit Unions arbeiten, du kannst aber auch die Chars zurecht setzen. Zweiteres kostet mehr Zeit, aber ist typsicher. Ersteres ist eine klare Einschränkung, was in dem Fall erlaubt ist und was nicht und kostet keine Rechenzeit.fat-lobyte hat geschrieben:Die implementierung möchte ich sehn, die ohne Casts auskommt. Wie willst du z.B. ein long und ein short zusammenhängend als Array Speichern? Entweder du Castest einen Zeiger auf dein char- array zu einem int, oder du nimmst nen Zeiger auf deine ints und castest diese nach char*. Nur weil du es in eine Klasse Kapselst, ist das Problem noch lange nicht weg.Xin hat geschrieben:C++ Lösung: Klasse erstellen, bestehend aus eigenen Longs, die sich als char-Array zurückgeben lassen.
Verwendest Du sie mehrfach, musst Du weniger casten. Wieder ist es möglich mit Unions klarzustellen, was von wo nach wo geht und im Code zu beschreiben, was gewünschtes, erlaubtes Verhalten ist und was nicht.fat-lobyte hat geschrieben:Ich sehe hier keinen Unterschied zu meiner Version, es sind genausoviele Casts drinnen, wie bei mir, nur sind sie schon wieder in Funktionen versteckt.
Dann pack die Funktion in ein Makro und fertig.fat-lobyte hat geschrieben:Ich brauche nicht für eine Funktion, die mir mal shcnell nen Paketheader zusammenbauen soll 2-3 unterfunktionen! Das ist alles Laufzeit, denn C89 hat keine inline- funktionen .... Das ganze 3 mal, und wenn das in einer Schleife geschieht geht kostbare Laufzeit verloren, und das für eine nicht-Lösung.
fat-lobyte hat geschrieben:Xin hat geschrieben:Grober Designfehler...
Pseodocode, oder einfache Beispiele drücken meist nicht das aus, was gemeint ist. In "Real World" Situationen gibt es nur sehr sehr selten perfekte Designs, oft sind verschiedene Design Patterns zusammengemischt und sind nur mit Kompromissen zueinander Kompatibel.
In diesem Fall ist "handler" keine globale Funktion, sondern eine callback Funktion von einer "Controller" Klasse, DerivedA und DerivedB sind Nachrichten, und werden von einer Klasse gesendet, die außer einem Funktionszeiger von der "Controller" Klasse nie etwas gesehen hat. Mag sein dass das design nicht Perfekt ist. Es ist aber ein guter Kompromiss, ich habe lange dran gefeilt (kannst Kerli fragen, wie ich ihn bei ICQ zugespammt habe).
Code: Alles auswählen
struct Base
{
virtual DerivedA * AsDerivedA() { return NULL; }
virtual DerivedB * AsDerivedB() { return NULL; }
};
struct DerivedA : public Base
{
DerivedA * AsDerivedA() { return this; }
};
struct DerivedB : public Base
{
DerivedB * AsDerivedB() { return this; }
};
Es gibt Gründe zum Casten, aber in der Regel daher, da die Sprache keine Alternative anbietet oder weil ein anderer Programmierer Mist gebaut hat.fat-lobyte hat geschrieben:Das ganze ist ein Feature, dass man "Vererbung" nennt, und dazu gehören diese Casts noch dazu. Diese Technik wird auch in Bibliotheken verwendet, die nicht unter den 10 schlechtesten Libs sind, und zwar wxWidgets. Da gibts zum Beispiel die wxEvent Klasse, die die Basisklasse für viele andere Klassen ist.
Was allerdings meist auch an Designfehlern liegt.fat-lobyte hat geschrieben:Nur Fakt ist: In echten Anwendungen, mit echten Bibltiotheken, echten Programmierern mit verschiedenen Programmierstilen ist es oft nicht zu vermeiden.
Jow, aber ein Typ sollte sagen, welche Interpretationen gewünscht sind und welche nicht. Union macht das. Casts setzen sich über alles hinweg.fat-lobyte hat geschrieben:Auch finde ich es etwas ungerecht vom "Armutszeugnis" zu sprechen und Casten grundsätzlich zu verteufeln. Und zwar nicht nur aus dem Grund dass es tausende (hunderttausende?) Programmierer gibt, und Millionen von Codezeilen in denen Casts vorkommen. Eine Ansammlung von Bits sind Daten, die Interpretiert werden. Manchmal ist es notwendig und sinnvoll diese Daten anders zu interpretieren.
Ich verteufle casten nicht. Aber es hat bei mir den Stellenwert eines Gotos: man sollte es möglichst nicht einsetzen.fat-lobyte hat geschrieben:Ich meine, man darf einfach nicht generell Sprachfeatures verteufeln. Natürlich soll man Casts vermeiden, natürlich soll man keine goto's anwenden und auch so wenig wie möglich mit dem Präprozessor machen. Aber all diese sprachfeatures haben ihre Nischen, und müssen manchmal verwendet werden.
Ich habe einige Zeit überlegt, ob ich Casts bei mir zulassen soll und mich dazu durchgerungen, sie zuzulassen, aber ich könnte mir gut vorstellen, einen Schalter einzubauen, der erst angegeben werden muss, um casts zu erlauben.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
- fat-lobyte
- Beiträge: 1398
- Registriert: Sa Jul 05, 2008 12:23 pm
- Wohnort: ::1
- Kontaktdaten:
Re: C:Ausdrücke
Du interpretierst ein Datum (einzahl von Daten) als etwas, was es gar nicht ist. Wieso hast du es z.B. nicht gleich als solchen Typ deklariert, der er wirklich ist?Dirty Oerti hat geschrieben:Mal ne Frage zwischenrein:
Was genau ist an Casts schlecht?
So zumindest die Grundregel. Ich finde es gibt ausnahmen zu dieser Regel. Xin findet dass es diese nicht gibt.
Haters gonna hate, potatoes gonna potate.
- Dirty Oerti
- Beiträge: 2229
- Registriert: Di Jul 08, 2008 5:05 pm
- Wohnort: Thurndorf / Würzburg
Re: C:Ausdrücke
Hm...die Definition von Cast kenn ich.
Aber was ist das schlechte dran?
Das ich etwas umdefiniere?
Hm..was ist schlecht daran, den Wertebereich zu verkleinern?
Ist ganz nützlich, wenn man nur den unteren Wertebereich haben möchte.
Aber was ist das schlechte dran?
Das ich etwas umdefiniere?
Hm..was ist schlecht daran, den Wertebereich zu verkleinern?
Code: Alles auswählen
long blub = 3423;
short dummy = (short) blub;
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne!
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.
Ich helfe gerne!

----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.
- fat-lobyte
- Beiträge: 1398
- Registriert: Sa Jul 05, 2008 12:23 pm
- Wohnort: ::1
- Kontaktdaten:
Re: C:Ausdrücke
wieso hast dus dann nicht gleich als "short" deklariert, wenn du nur den unteren Wertebereich brauchst?
Haters gonna hate, potatoes gonna potate.
- Dirty Oerti
- Beiträge: 2229
- Registriert: Di Jul 08, 2008 5:05 pm
- Wohnort: Thurndorf / Würzburg
Re: C:Ausdrücke
Beispiel:
Ich habe einen Wert im Wertebereich von long. (Den gibt mir so z.b. der Benutzer ein)
Nun muss ich diesen Wert speichern.
Allerdings muss ich einmal den unteren Teil, ein anderes mal den oberen Teil speichern.
Eventuell muss ich auch viele solcher Werte speichern.(In einem Array)
Und ich hab die Eingabe:
Wenn ich nun ohne Casts arbeite oder mir das Leben schwer machen will, dann brauch ich folgende struct:
Dabei könnte ich auch diese hier nehmen:
Die verbraucht viel weniger Speicher.
Außerdem ist mit einem kurzem Cast und einer Verschiebung alles fertig. Und das dann auch noch schnell.
Während ich bei der Methode ohne Cast erstmal das Unnötige wegbekommen muss.
*Hoffentlich verständlich*
MfG
Daniel
Ich habe einen Wert im Wertebereich von long. (Den gibt mir so z.b. der Benutzer ein)
Nun muss ich diesen Wert speichern.
Allerdings muss ich einmal den unteren Teil, ein anderes mal den oberen Teil speichern.
Eventuell muss ich auch viele solcher Werte speichern.(In einem Array)
Code: Alles auswählen
struct der_wert Wertarray[2000]
Code: Alles auswählen
long eingabe = /*großer Wert*/;
Code: Alles auswählen
struct der_wert
{
long oben;
long unten;
}
Code: Alles auswählen
struct der_wert
{
short oben;
short unten;
}
Außerdem ist mit einem kurzem Cast und einer Verschiebung alles fertig. Und das dann auch noch schnell.
Während ich bei der Methode ohne Cast erstmal das Unnötige wegbekommen muss.
*Hoffentlich verständlich*
MfG
Daniel
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne!
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.
Ich helfe gerne!

----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.
- Xin
- nur zu Besuch hier
- Beiträge: 8862
- Registriert: Fr Jul 04, 2008 11:10 pm
- Wohnort: /home/xin
- Kontaktdaten:
Re: C:Ausdrücke
Ich schreib doch schon, dass es Ausnahmen gibt... aber die weisen auf einen Mangel hin. Wenn es nicht im Programmdesign liegt (egal ob in meinem oder dem der Lib, die ich nutze), dann auf einen Mangel Design der Programmiersprache.fat-lobyte hat geschrieben:So zumindest die Grundregel. Ich finde es gibt ausnahmen zu dieser Regel. Xin findet dass es diese nicht gibt.
Bevor man castet sollte man Alternativen suchen - bei meinem aktuellen Array-Template caste ich viel, weil ich noch auf keine schönere Lösung gekommen bin.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.