C Struct arbeiten

Gast #5976421
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
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.
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
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
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
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
}
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

Eine eigene Frage? Dieser Thread ist über 7 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.