Hallöchen, eine union kann man ja gut benutzen für so etwas in der Art: typedef struct{ U8 x; //Koordinate U8 y; //Koordinate }point_t; typedef union{ U16 alle; point_t einzeln; }xy_u; xy_u xy; xy.einzeln.x = 3; xy.einzeln.y = 4; mach_irgendwas(xy); xy.alle = 0; //Alle auf einen Streich gelöscht Aber wie stelle ich das beispielhaft für nachfolgendes an? typedef struct{ U8 x; //Koordinate U8 y; //Koordinate U8 z; //Koordinate }point_t; typedef union{ U24 alle; //3-byte gibts aber nicht...! point_t einzeln; }xyz_u; Da die union wiederum in einer längeren Tabelle verwendet wird, möchte ich nicht z.B. U32 verbraten, wenn theoretische U24 reichen würde. typedef struct{ xyz_u xyz; U8 foo; }table_t; table_t table[] = {/* viele Einträge*/};
Hi, Frank-in-der-Beta-Version :-) was sagt Dein Assembler-Listing? Legt der Compiler structs mit 1* u16 und 1* u8-Variablen lückenlos an, oder läßt er sowieso eine Lücke? Ist das progmem-Konstanten genauso wie bei RAM und EEPROM? Falls er structs mit einer ungeradzahligen Anzahl u8 lückenlos packt, wüßte ich keine bessere Lösung als die Tabelle als point_t liste[] zu speichern und die union xy_u nur innerhalb einer Funktion zu deklarieren. Ciao Wolfgang Horn
Hi beta-frank
> eine union kann man ja gut benutzen für so etwas in der Art:
Mach das nicht.
In diesem Fall kannst du wie folgt vorgehen:
point_t xy;
xy.x = 0;
xy.y = 0;
oder meinetwegen
xy.x = xy.y = 0;
aber geh nicht den Weg über eine union. Würde mich sehr wundern
wenn das langsamer oder schneller wäre als die Zuweisung über
die union.
Selbst die Verwendung einer union um einen bestimmten Datentyp in
Bytes aufzudröseln ist genau genommen vom C-Sprachstandard nicht
gedeckt. Deine Variante ist weit davon entfernt auch nur ansatzweise
legal zu sein.
Wenn du unbedingt eine Struktur in einem Rutsch auf
alle Bytes 0 setzen willst, dann mach das so:
memset( &xy, 0, sizeof( xy ) );
das ist legal und funktioniert auch dann, wenn der Compiler
Padding benutzt. Das Monster kannst du, wenn du willst noch
in einem schicken Makro verpacken:
#define CLEAR(x) memset( &(x), 0, sizeof( x ) )
und damit schreiben:
point_t xy;
CLEAR( xy );
Danke für Eure Antworten! Wenn ich über das beta-Stadium schon hinaus wäre, bräuchte ich ja nicht fragen;-)) Ich versuche, nochmal genauer zu erklären was ich erreichen möchte: Ich bekomme 6 U8 Werte nacheinander, die ich einzeln und nacheinander ermittle und erstmal in einer Structvariablen ablege/sammle. Es gibt nur rund 20 verschiedene Kombinationen der 6 Werte, welche ich nun mittels einer Tabelle ermitteln will (und dann die entsprechene Callback aus 20 möglichen Callbacks aufrufen kann). Das ganze darf aber auch nicht allzu viel Rechenzeit benötigen. Mein nächster Ansatz ist nun (Beispielhaft wieder mit 3 U8-Variablen)
1 | typedef struct{ |
2 | U8 x; //Koordinate |
3 | U8 y; //Koordinate |
4 | U8 z; //Koordinate |
5 | }point_t; |
6 | |
7 | typedef struct{ |
8 | point_t xyz; |
9 | PFKT pfkt; //Funktionszeiger auf Callback |
10 | }table_t; |
11 | |
12 | table_t table[] = { |
13 | {{1,2,3},callback_1}, |
14 | {{7,8,9},callback_2}, |
15 | };
|
16 | |
17 | void main(void){ |
18 | point_t live={7,8,9}; |
19 | U8 cnt; |
20 | for(cnt=0; cnt<sizeof(table)/sizeof(table_t); ++cnt) |
21 | if( strncmp((char*)&table[cnt], (char*)&live, sizeof(point_t))==0) |
22 | table[cnt].pfkt();//TabellenÜbereinstimmung gefunden |
23 | }
|
Würde mich über einen Kommentar / Verbesserungsvorschlag freuen. Frank
PS: das sinnvlolle
1 | break; |
, um in der for-Schleife nicht unnötig länger zu weilen liefere ich hiermit nach;-)
Hi Frank, ich wage zu bezweifeln, das Du mit einem String-Vergleich den korrekten Punkt in Deiner Tabelle findest! besser?:
1 | typedef struct{ |
2 | U8 x; //Koordinate |
3 | U8 y; //Koordinate |
4 | U8 z; //Koordinate |
5 | }point_t; |
6 | |
7 | typedef struct{ |
8 | point_t xyz; |
9 | PFKT pfkt; //Funktionszeiger auf Callback |
10 | }table_t; |
11 | |
12 | table_t table[] = { |
13 | {{1,2,3},callback_1}, |
14 | {{7,8,9},callback_2}, |
15 | };
|
16 | |
17 | bool equalPoints(point_t p1, point_t p2) |
18 | {
|
19 | return ( ( p1.x == p2.x ) && |
20 | ( p1.y == p2.y ) && |
21 | ( p1.z == p2.z ) ); |
22 | }
|
23 | |
24 | void main(void){ |
25 | point_t live={7,8,9}; |
26 | U8 cnt; |
27 | for(cnt=0; cnt<sizeof(table)/sizeof(table_t); ++cnt) |
28 | if( equalPoints(table[cnt].xyz, live) |
29 | table[cnt].pfkt();//TabellenÜbereinstimmung gefunden |
30 | }
|
> ich wage zu bezweifeln, das Du mit einem String-Vergleich den > korrekten Punkt in Deiner Tabelle findest! Yep. @Frank Die Idee die du hattest, ist doch dass alle Bytes identisch sein muessen. Hier reden wir von Bytes, d.h. die str... Funktionen sind keine gute Wahl. Unter anderem deshalb da bei Strings es ja einen Bytewert mit einer ganz bestimmten Bedeutung gibt. Das 0-Byte und es bedeutet 'End of String'. Alle str... Funktionen wissen das und behandeln das auch entsprechend. Wenn du auf Byte-Ebene arbeitest: mem... Funktionen Wenn die Bytes zusätzlich noch die Vorausssetzungen für einen String erfüllen: str... Funktionen Oder aber das ganze klassisch ausprogrammieren, so wie Karsten das vorschlägt.
Die Variante
1 | bool equalPoints(point_t p1, point_t p2) |
2 | {
|
3 | return ( ( p1.x == p2.x ) && |
4 | ( p1.y == p2.y ) && |
5 | ( p1.z == p2.z ) ); |
6 | }
|
werde ich verwenden. Ich dachte, strncmp(..) (ausgesprochen vermutlich String_N_Compare) vergleicht stur N zeichen ohne auf '\0' zu achten. Achtet sie aber... Vielen Dank für Eure Unterstützung! Frank
> Ich dachte, strncmp(..) (ausgesprochen vermutlich > String_N_Compare) vergleicht stur N zeichen ohne auf '\0' zu achten. strncmp benutzt man gerne zum Parsen wenn man eine Eingabezeile hat und zb. weiss dass die mit einem bestimmten Schlüsselwort anfangen muss. zb. Hast du ein Protokoll POINT 2, 20, 30, 40 LINE 5, 6 Um jetzt festzustellen ob das eine POINT oder eine LINE Zeile ist, kannst du machen: if( strncmp( Input, "POINT", 5 ) == 0 ) // war ein POINT else if( strncmp( Input, "LINE", 4 ) == 0 ) // war ein LINE
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.