Struct mit unveränderlichen Elementen (const ...), wie realisieren?
-
Hallo,
hier ein weiteres Problem, über das ich gestolpert bin:
Ich will ein Struct definieren ...
typedef struct { int maxsize; int size; } my_struct;
... dabei soll my_struct->maxsize, nachdem es initialisiert wurde, nicht mehr geändert werden können.
Offenbar kann ich aber mit folgendem Struct nicht arbeiten, ...
typedef struct { const int maxsize; int size; } my_struct;
... weil sowie ich my_struct leer angelegt habe my_struct m;, kann ich maxsize überhaupt nicht mehr initialisieren m->maxsize=34;, da es schreibgeschützt ist.
Aber das ist Quark!
Ich will es doch mindestens einmal setzen können, bevor es nicht mehr verändert werden kann.Momentan benutze ich einen m.M. nach quick&dirty workaround, um dieses Problem zu umgehen, ...
const int maxsize=34; typedef struct { int *mxsize=&maxsize; int size; } my_struct;
... aber das ist auch Quark so, weil sich maxsize ausserhalb des Structs befindet. Dagegen habe ich design-technische Einwände. Ausserdem gibt es keine Garantie, dass *int mxsize; auf einen schreibgeschützen int zeigt.
Wie geht denn das in ANSI C überlicherweise, dass man Elemente in Structs unveränderlich macht?
PS:
Naja, eigentlich kann man auch entsprechende getter- und setter-Funktionen/Prozeduren fürs jeweilige Struct definieren, die man benutzen sollte, statt direkt mit dem Struct zu arbeiten, aber hey... das ist ANSI C, nicht Java, deswegen gibts dafür keine Garantie, dass nicht irgndwie doch ein Element verändert wird, dass schreibgeschützt sein sollte...
-
--
-
DerGrosseC schrieb:
... weil sowie ich my_struct leer angelegt habe my_struct m;, kann ich maxsize überhaupt nicht mehr initialisieren m->maxsize=34;, da es schreibgeschützt ist.
das geht z.b. so: my_struct m = {10};
damit wird m.maxsize auf 10 gesetzt. das geht aber nur beim anlegen der struct.DerGrosseC schrieb:
das ist ANSI C, nicht Java, deswegen gibts dafür keine Garantie, dass nicht irgndwie doch ein Element verändert wird, dass schreibgeschützt sein sollte.
richtig, die gibts nicht. 'const' ist eigentlich mehr sowas wie ein compiler-switch. du versprichst dem compiler mit 'const', dass du die variable nicht verändern willst und im gegenzug darf er gewisse optimierungen anwenden.
-
Hi!
typedef struct { const int maxsize; int size; } my_struct; my_struct a; // a.maxsize ist hiermit mit 'Datenschrott' initialisiert und lässt sich nicht mehr ändern. my_struct b = {100}; // a.maxsize = 100;
Gruß,
B.B.
-
Big Brother schrieb:
Hi!
typedef struct { const int maxsize; int size; } my_struct; my_struct a; // a.maxsize ist hiermit mit 'Datenschrott' initialisiert und lässt sich nicht mehr ändern. my_struct b = {100}; // a.maxsize = 100;
Gruß,
B.B.Ohh!
Das ist ja ein böser Hack!
Ok. Habs verstanden.
Gute Frage, nächste Frage:
Damit binde ich aber die Definition meiner Structmember an eine bestimmte Reihenfolge (const maxsize, steht als erstes Element).
Wie mach ich das denn hiermit?:
typedef struct { const maxsize; int cursize; const favorite_char; foo bar; /* ... */ } my_struct;
Etwa so:
my_struct m = {42, NULL, '?'};
Wenn's da keine Möglichkeit gibt, auch nicht schlimm. Ich kann damit trotzdem mit der o.g. Methode arbeiten,
aber interessant ist die Frage dennoch...Danke!
-
Seit C99:
my_struct m = { .favorite_char = '?' };
-
Hey genau,
ich hab' eine Idee! (Raus damit du Sau!)
Für jeden Datentypus und für jede schreibgeschütze Variable des Datentypus
lege ich ein bis <Anzahl der Datentypen in ANSI C> Arrays an mit jeweils ein bis <Anzahl der Elemente desselben Datentyps> Elementen, jeweils am Anfang des Structs an. DAS IST DER WAHRHEIT! (~=Das ist die Lösung.)typdef struct { const int[4] foo; const char[2] bar; /* ... */ } kompliziert;
Merke im Kopf:
maxsize (schreibgeschützt) = kompliziert.foo[0]
minsize (schreibgeschützt) = kompliziert.foo[1]
foosize (schreibgeschützt) = kompliziert.foo[2]
barsize (schreibgeschützt) = kompliziert.foo[3]
coolchr (schreibgeschützt) = kompliziert.bar[0]
doofchr (schreibgeschützt) = kompliziert.bar[1]
usw...Dann:
kompliziert k = { {maxsize,minsize,foosize,varsize}, {coolchr,doofchr} /* usw... */ };
Gute Idee, was?
Allerdings müssen dann in jeden Fall alle schriebgeschützen Variablen zum Zeitpunkt der Initialisierung des Structs 100% feststehen, was denn Einsatzzweck wohl etwas einschränken dürfte..., hmmm.
-
Tim schrieb:
Seit C99:
my_struct m = { .favorite_char = '?' };
Ha!
Das ist ja noch geiler!
Aber sorry jetzt regt es mich echt auf.
In kaum einer SCHEISS C-Referenz kommt dieses Beispiel vor.
Das liegt wohl daran, dass in den meisten Referenzen überhaupt
keine Beispiele vorkommen, nur stumpfe, dumme Spezifikationen auf lexikalischer (Grund-)Basis,
ohne auf solche Möglichkeiten auch im geringsten hinzuweisen.Glücklicherweise gibts erfahrene Benutzer und "inoffizielle" Quellen, wie dieses Forum,
weil DAS DA OBEN, stehen in keinem meiner Bücher oder Online Dokumentationen/Refs über ANSI-C.Danke!
-
DerGrosseC schrieb:
In kaum einer SCHEISS C-Referenz kommt dieses Beispiel vor.
Die meissten Bücher, Referenzen, etc. sind auch nicht für C99 geschrieben.
MFG
r.b.b.
-
ruhig blut brauner schrieb:
Die meissten Bücher, Referenzen, etc. sind auch nicht für C99 geschrieben.
Stimmt auch wieder, aber dafür gibts auch kaum noch Compiler, die C99 nicht unterstützen, deswegen käst mich das irgendwo doch noch an, dass derartige Informationen irgendwie "unter gehen" oder irgendwo "zwischen den Zeilen" bzw "im kleingedruckten" stehen.
Appropos: Wo gibts denn Umfangreiche C99 Doks/Specs/Refs? ... in der Qualität folgender ANSI-C Doks:
http://www.java2s.com/Code/C/CatalogC.htm
http://c-faq.com/
http://www.acm.uiuc.edu/webmonkeys/book/c_guide/
...
Es gibt sooo viele Beispiele...