Forum: PC-Programmierung C: Strukt zugriff auf n. Element innerhalb des Structs


von Michael H. (overthere)


Lesenswert?

Hallo,
ich habe einen Struct:
double a,b,c,d,e,f,... in einem Strukt. Da möchte ich nun das n. Element 
des Structs manipulieren.
Also statt struct->c z.B. struct->val, wobei val=3 ist, sodass ich durch 
val iterieren kann. Wie kann ich sowas machen?
Grüße

von Helmut L. (helmi1)


Lesenswert?

struct[3]->c

von Karl H. (kbuchegg)


Lesenswert?

Michael H. schrieb:
> Hallo,
> ich habe einen Struct:
> double a,b,c,d,e,f,... in einem Strukt. Da möchte ich nun das n. Element
> des Structs manipulieren.
> Also statt struct->c z.B. struct->val, wobei val=3 ist, sodass ich durch
> val iterieren kann. Wie kann ich sowas machen?

Indem du nicht a, b, c, d, e, f, ... machst sondern ein Array von 
Werten.

von Michael H. (overthere)


Lesenswert?

Die 1. Lösung ist falsch. Die 2. ist der prinzipelle Ansatz den man 
verfolgt wenn man nochnicht 10k Lines geschrieben hat.
Ich habe jetzt eine Funktion geschrieben, die die einzelnen Cases 
abfängt. Nicht gerade sauber, aber funktioniert.

von (prx) A. K. (prx)


Lesenswert?

Michael H. schrieb:

> verfolgt wenn man nochnicht 10k Lines geschrieben hat.
> Nicht gerade sauber, aber funktioniert.

Um sauberen Code zu schreiben darf man also keine 10K Zeilen geschrieben 
haben?

Technisch ist das geschenkt [Prinzip *(&p->a + n)], aber hoffnungslos 
schlechter Stil und das Verhalten ist mindestens formal nicht definiert.

von Karl H. (kbuchegg)


Lesenswert?

Michael H. schrieb:
> Die 1. Lösung ist falsch. Die 2. ist der prinzipelle Ansatz den man
> verfolgt wenn man nochnicht 10k Lines geschrieben hat.

Ist nicht wirklich ein Problem.
Manchmal muss man auch ins kalte Wasser springen und einfach machen.
Der Compiler hilft ja dabei indem er alle zu ändernden Stellen raussucht 
und markiert. Und der Rest ist dann einfach Fehlermeldungen abarbeiten 
und die Ersetzung machen. Wenn man sich traut und seinen Code kennt, 
kann man sich mit einem Editor-Replace viel Arbeit im Vorfeld schon 
abnehmen lassen.

Eine Möglichkeit (wenn auch nicht 100% koscher), wäre es, die 
betreffenden Strukturelemente mittels einer Union mit einem Array zu 
überlagern.

von Vlad T. (vlad_tepesch)


Lesenswert?

"nicht koscher" im Sinne von "laut c-Standard undefiniert".
Unions haben nur definierte Werte, wenn genau der Teil ausgelesen wird, 
der auch beschrieben wurde, wenn ich mich recht erinnere.

trotzdem ist es beliebte Praxis Unions zum Konvertieren von Datentypen 
in Bytearrays zu benutzen - scheint also meistens zu funktionieren ;)

von Karl H. (kbuchegg)


Lesenswert?

Vlad Tepesch schrieb:
> "nicht koscher" im Sinne von "laut c-Standard undefiniert".
> Unions haben nur definierte Werte, wenn genau der Teil ausgelesen wird,
> der auch beschrieben wurde, wenn ich mich recht erinnere.

Du erinnerst dich richtig.

> trotzdem ist es beliebte Praxis Unions zum Konvertieren von Datentypen
> in Bytearrays zu benutzen - scheint also meistens zu funktionieren ;)

Nicht nur meistens.
Bis vor einigen Jahren war definitiv kein Compiler bekannt, bei dem es 
nicht funktioniert hätte. Und man kann davon ausgehen, dass kein 
Compilerhersteller in der Zwischenzeit damit gebrochen hätte. Das hätte 
für ihn ein echtes Manko dargestellt. Auch wenn er im Recht gewesen 
wäre.

Daher "nicht koscher". Laut C-Standard nicht gedeckt - allerdings greift 
die normative Kraft des Faktischen.

von Vlad T. (vlad_tepesch)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Vlad Tepesch schrieb:
>> "nicht koscher" im Sinne von "laut c-Standard undefiniert".
>> Unions haben nur definierte Werte, wenn genau der Teil ausgelesen wird,
>> der auch beschrieben wurde, wenn ich mich recht erinnere.
>
> Du erinnerst dich richtig.

rein theoretisch könnte man unions als struct implementieren, oder steht 
irgendwo, dass sizeof(union) = max(sizeof(unionmember)) sein muss?

von Stefan E. (sternst)


Lesenswert?

Vlad Tepesch schrieb:
> rein theoretisch könnte man unions als struct implementieren, oder steht
> irgendwo, dass sizeof(union) = max(sizeof(unionmember)) sein muss?

Nein, nur sizeof(union) >= max(sizeof(unionmember)).
Aber der Standard fordert, dass alle Unionmember auf der selben Adresse 
liegen müssen.

von Vlad T. (vlad_tepesch)


Lesenswert?

ah, ok

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Vlad Tepesch schrieb:
> "nicht koscher" im Sinne von "laut c-Standard undefiniert".
> Unions haben nur definierte Werte, wenn genau der Teil ausgelesen wird,
> der auch beschrieben wurde, wenn ich mich recht erinnere.

Jepp. Allerdings gibt zumindest GCC einen Persilschein [1] [2]:

> To fix the code above, you can use a union instead of a cast
> (note that this is a GCC extension which might not work with
> other compilers):

[1] http://gcc.gnu.org/bugs/#nonbugs
[2] 
http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html#Structures-unions-enumerations-and-bit_002dfields-implementation

von Finsbury (Gast)


Lesenswert?

einfach durch struct-Elemente iterieren so wie ich das verstanden habe 
geht schon, wenn die Elemente denselben Datentyp haben. Ich weiß nicht 
wie sich das mit gutem Stil deckt aber mit Zeigern in etwa:
1
struct {
2
double a,b,c,d,e; 
3
}dVar; // die Strukturvariable
4
5
double *p=(double) &dVar; // zeiger auf erstes struct-Element 
6
7
for(int i=0;i<sizeof(dVar)/sizeof(double);i++)
8
p[i]=i;

ohne das compiliert zu haben meine ich, dass dVar.a bis dVar.e nun mit 
0 bis 4 initialisiert sind.

Mache ich zB. in der WinAPI-Programmierung so, um z.B. bestimmte 
Fensterhandles zu gruppieren und in einem Rutsch zB. an oder 
auszuknipsen.
Muss man eben gucken, dass man mit sowas sicher handhabt.

von Finsbury (Gast)


Lesenswert?

Das int auf double zugewiesen ohne zu casten sei mir verziehen. Ist ja 
auch nur ein Beispiel.

von (prx) A. K. (prx)


Lesenswert?

Finsbury schrieb:

Wozu der Cast?
1
double *p = &dVar.a; // zeiger auf erstes struct-Element

von (prx) A. K. (prx)


Lesenswert?

Finsbury schrieb:

> Das int auf double zugewiesen ohne zu casten sei mir verziehen.

Auch hier: Weshalb wäre es mit Cast besser? Jeder unnötige Cast 
reduziert die Chancen des Compilers, dir sinnvolle Fehlermeldungen und 
Warnungen zu liefern. Wenn du alles kreuz und quer castest, dann ist ab 
und zu mal einer dabei, der Schrott ist.

von Finsbury (Gast)


Lesenswert?

ich denke an der Stelle ist das ungefährlich. ansonsten hast du recht ;)
lass das Beispiel einfach Beispiel sein.

von Vlad T. (vlad_tepesch)


Lesenswert?

Finsbury schrieb:
> einfach durch struct-Elemente iterieren so wie ich das verstanden habe
> geht schon, wenn die Elemente denselben Datentyp haben. Ich weiß nicht
> wie sich das mit gutem Stil deckt aber mit Zeigern in etwa:

Ich würde sowas lassen.
wenn man iterieren will, ist so eine Strukturdefinition einfach schrott.
Dann sollte man nicht versuchen mit irgendwelchen schmutzigen Tricks 
trotzdem zum Ziel zu kommen, sondern den Code überarbeiten, bevor man 
sich böse Fehler rein holt.

von Finsbury (Gast)


Lesenswert?

Vlad Tepesch schrieb:
> wenn man iterieren will, ist so eine Strukturdefinition einfach schrott.

Vom Grundsatz: warum? Speicher ist Speicher, ob nun als Array oder 
struct formuliert. Kommt drauf an, warum es gerade ein struct sein muss 
und darum geht es nach der Eingangsfrage nicht, sondern ob es geht.

> irgendwelchen schmutzigen Tricks
indem man Grundkonstrukte der Programmiersprache anwendet?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Finsbury schrieb:
> Vlad Tepesch schrieb:
>> wenn man iterieren will, ist so eine Strukturdefinition einfach schrott.

Seh ich auch so. Hier liegen die Stekt-Komponenten zwar dich, das ist 
aber nicht unbedingt der Fall und u.a. vom ABI un Datentyp abhängig.

von Karl H. (kbuchegg)


Lesenswert?

Finsbury schrieb:
> Vlad Tepesch schrieb:
>> wenn man iterieren will, ist so eine Strukturdefinition einfach schrott.
>
> Vom Grundsatz: warum?

Weil es noch nie eine gute Idee war, das falsche Werkzeug für einen 
bestimmten Zweck einzusetzen.

von Vlad T. (vlad_tepesch)


Lesenswert?

Finsbury schrieb:
> Vlad Tepesch schrieb:
>> wenn man iterieren will, ist so eine Strukturdefinition einfach schrott.
>
> Vom Grundsatz: warum?

Ich hab auch noch eine Begründung:
Optimizer und Annahmen, was Aliasing (bzw dessen Abwesenheit) angeht.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Johann L. schrieb:
> Hier liegen die Stekt-Komponenten zwar dich

Welch wunderbare Worte, doch was magst Du damit meinen?

von Vlad T. (vlad_tepesch)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Johann L. schrieb:
>> Hier liegen die Stekt-Komponenten zwar dich
>
> Welch wunderbare Worte, doch was magst Du damit meinen?

lol, das hab ich mich auch gefragt.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rufus Τ. Firefly schrieb:
> Johann L. schrieb:
>> Hier liegen die Stekt-Komponenten zwar dich
>
> Welch wunderbare Worte, doch was magst Du damit meinen?

Oje. Too-many-fingers-on-keyboard-error.

"Hier liegen die Strukt-Komponenten zwar dicht"

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.