Forum: Mikrocontroller und Digitale Elektronik C Struct arbeiten


von Vorgestern (Gast)


Lesenswert?

Moin, ich hab ein Struct
1
typedef struct{
2
    int speedR;
3
    int speedL;
4
    int encR;
5
    int encL;
6
} encoder_t;

Ich möchte jetzt eine Ausgabe schreiben. Wie kann ich in einer Schleife 
die Einträge automatisch abrufen. In der Art:
1
encoder_t encoder1;
2
...
3
for(int i=0; i<4; i++){
4
   printf("%d", encoder1.[i]);
5
}

Wie gehts richtig? (Umgekehrtes Enum?)
Ausgabe für jeden einzelnen Eintrag händisch erstellen? (Hab ein Struct 
welches noch mehr Inhalte beinhaltet..)
Gar kein Struct nutzen?
Andere Möglichkeiten sowas gut zu händeln?

von Dr. Sommer (Gast)


Lesenswert?

Das geht aus Prinzip nicht. Die Einträge eines struct können 
unterschiedliche Typen haben, welche unterschiedlich behandelt werden 
müssen, und daher nicht in einer Schleife iteriert werden können.

Du kannst ein Array nutzen und mit einem enum fixe Indizes für die 
Einträge definieren, oder eine union aus Array und Einträgen (gefährlich 
+ hässlich), oder einfach die 4 Einträge manuell per printf ausgeben - 
falls du die nicht noch an vielen anderen Stellen im Code iterieren 
musst.

In C++ kann man sich eine statische Iteration bauen welche automatisch 4 
printf Statements generiert - hier aber ziemlicher Overkill.

von Peter D. (peda)


Lesenswert?

Da muß man sich entscheiden, entweder struct oder array.
Man kann zwar eine Union aus struct und array machen, aber das ist 
unsauber.
Sauber ist, ein Array zu nehmen und die Elemente über ein Enum 
anzusprechen.

von Patrick C. (pcrom)


Lesenswert?

Dies waehre eine moeglichkeit :
1
typedef union {
2
    struct {
3
        uint8 data[NRF_PKSIZE];
4
    } raw;
5
    struct {
6
        uint8   NrfCmd;
7
        uint8   Future;
8
        uint8   ssize;
9
        uint8   rsize;
10
        uint8   sbuf[28];
11
    } s;
12
} s_NrfPacket;

Aber wie schon gesagt von Peter D, das ist unsauber.
zB :
* Andere compilers koennten unterschiedliche speicher-definitionen haben
* Andere prozessoren koennten unterschiedliche speicher-definitionen 
haben
* Manchmal wird in ein struct mehr platz reserviert dann wirklich 
benotigt
Und wahrscheinlich noch mehrere nachteilen... Aber fuer mich 
funktioniert es.

Patrick

von TriHexagon (Gast)


Lesenswert?

Oder einfach eine Funktion definieren dir die Indexe auf die Elemente 
abbildet (Mapping-Funktion). Dann kannst du das Struktur behalten und 
kannst die Elemente trotzdem indexieren. Keine ekligen Unions nötig und 
auch kein Array.

In C++ könnte man auch mittels der Operatorenüberladung genau die Syntax 
haben, die du verwendest.

von zitter_ned_aso (Gast)


Lesenswert?

Vorgestern schrieb:
> Enum

ich würde es so machen:
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <inttypes.h>
4
5
typedef enum {speedR,speedL, encR, encL, ENC_DATA_LEN} enc_iterator;
6
7
typedef struct{
8
    int encoder_data[ENC_DATA_LEN];
9
} encoder_t;
10
11
void print_encoder_data(encoder_t* e){
12
    for(enc_iterator i=speedR; i<ENC_DATA_LEN; i++)
13
       printf("%d\n", e->encoder_data[i]); 
14
15
}
16
17
int main(int argc, char* argv[]){
18
19
20
    encoder_t enc;
21
    enc.encoder_data[speedR]=1;
22
    enc.encoder_data[speedL]=2;
23
    enc.encoder_data[encR]=3;
24
    enc.encoder_data[encL]=4;
25
    
26
    print_encoder_data(&enc);
27
28
    return 0;
29
}

von x^2 (Gast)


Lesenswert?

Die Array-Lösung hat das Problem, dass Padding/Alignment der struct 
ignoriert wird und es Umsortierungen in der struct nicht nachzieht. 
Ebenso unsauber aber etwas komfortabler:
1
encoder_t x;
2
3
static const uint8_t at[] = 
4
{
5
   offsetof(x, speedR), 
6
   offsetof(x, speedL),
7
   offsetof(x, encR),
8
   offsetof(x, encL)
9
};
10
11
for (int i = 0; i < sizeof(at)/sizeof(at[0]); ++i)
12
{
13
   int element = ((const int*)&x)[at[i]/sizeof(int)];
14
   printf("%d\n", element);
15
}

von Walter K. (walter_k488)


Lesenswert?

Vorgestern schrieb:
> typedef struct{
>     int speedR;
>     int speedL;
>     int encR;
>     int encL;
> } encoder_t;
>
> Ich möchte jetzt eine Ausgabe schreiben. Wie kann ich in einer Schleife
> die Einträge automatisch abrufen

Indem Du Pointer verwendest, die auf die einzelnen Strukturelemente 
zeigen.
Da in Deinem Beispiel alle Elemente vom gleichen Datentyp sind - ist 
dieser Weg problemlos möglich.

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.