C Struct arbeiten

Gast #5976421
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?
Gast #5976442
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.
#5976453
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
Gast #5976454
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.
Gast #5976462
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
}
Gast #5976471
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
}
#5977529
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren