Array in Struktur füllen

Gast #2281275
Lesenswert?

nabend !

ich komm grad irgendwie nicht weiter und frag dehalb mal graderaus:

was mach ich hier falsch:

ich will den dateninhalt einer struktur welche nicht global oder 
statisch ist initialisieren.
1
.......
2
typedef struct s_picture            // Struktur für ein Einzelbild
3
{
4
    int             pic_id;     // ID des Einzelbildes innerhalb der Animation
5
    int             ani_id;     // ID der dazugeörigen Animation
6
    int             ms_pause;   // Anzeigedauer des Einzelbildes
7
    unsigned char   matrix[5][5][5];    //125 Byte Matrix der einzelnen LEDs
8
} s_pic;
9
.......
10
void clear_s_picture(s_pic *bild)
11
{
12
    bild->pic_id=0;
13
    bild->ani_id=0;
14
    bild->ms_pause=1000;
15
    bild->matrix=  {
16
    {    {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }    }  ,
17
    {    {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }    }  ,
18
    {    {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }    }  ,
19
    {    {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }    }  ,
20
    {    {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }  ,  {  0,  0,  0,  0,  0  }    }
21
};
22

23

24

25
}

gibt beim kompilieren in zeile
  bild->matrix=  {
den fehler:

main.c|169|error: expected expression before ‘{’ token|

keine Ahnung !

Muß ich jedes Element des Arrays einzeln auf 0 setzen ??

mfg marco
Persönliche Seite #2281300
Lesenswert?

Da gibt's mehrere Möglichkeiten
1
typedef struct
2
{
3
    int pic_id;
4
    int ani_id;
5
    int ms_pause;
6
    unsigned char matrix[5][5][5];
7
} s_pic;
8

9
#define N {0, 0, 0, 0, 0 }
10

11
void clear_s_picture (s_pic *bild)
12
{
13
    *bild = (s_pic) 
14
    {
15
        0, 0, 1000,
16
        { 
17
            { N, N, N, N, N },
18
            { N, N, N, N, N },
19
            { N, N, N, N, N },
20
            { N, N, N, N, N },
21
            { N, N, N, N, N }
22
        }
23
    };
24
}
25
#undef N
26

27
#include <string.h>
28

29
void clear_s_picture2 (s_pic *bild)
30
{
31
    memset (bild, 0, sizeof (s_pic));
32
    
33
    bild->ms_pause = 1000;
34
}

wohei die erste nicht standardkonform ist, wenn ich mich recht erinnere 
(GNU-C).

Die zweite Variante dürfte merklich effizienter sein.

Als dritte Möglichkeit gibt's nocht: ne (statische) Variable mit 
Initializer anlegen und kopieren.
Gast #2281342
Lesenswert?

Ja Ok ich sehe die struktur will als ganzes initialisiert werden

deine zweite lösung probier ich nachher mal aus, die is schön kurz.

um große arrays zu füllen hab ich auch memcpy benutzt , aber da brauch 
man ja auch ne vorlage. memset is da doch eleganter.

danke das hilft mir weiter

mfg marco
Moderator #2281579
Lesenswert?

Johann L. schrieb:
> wohei die erste nicht standardkonform ist, wenn ich mich recht erinnere
> (GNU-C).

Doch (C99).

> Die zweite Variante dürfte merklich effizienter sein.

GCC 4.6.1 mit -Os erzeugt für beide Varianten exakt den gleichen Code.
Mit -O2 oder -O3 ist die memset-Variante größer und etwas langsamer, da
der GCC dort memset-Code generiert, der für eine variable und nicht für
eine bekannterweis durch 4 teilbare Blockgröße optimiert ist.
Persönliche Seite #2282379
Lesenswert?

Yalu X. schrieb:

> Mit -O2 oder -O3 ist die memset-Variante größer und etwas langsamer, da
> der GCC dort memset-Code generiert, der für eine variable und nicht für
> eine bekannterweis durch 4 teilbare Blockgröße optimiert ist.

hmmm. Eigentlich kann GCC das, wär evtl. ne Frage in 
gcc-help@gcc.hnu.org wert.  Möglicherweise liegt's daran, daß nicht 
bekannt ist, ob bild aligned ist.  Hilft __attribute__((aligned(4)))?
Moderator #2282582
Lesenswert?

Johann L. schrieb:
> Hilft __attribute__((aligned(4)))?

Nein, das ändert überhaupt nichts.

GCC mit -O2 unterscheidet bei memset zwischen variabler und fester
Blockgröße. Bei variabler Größe wird memset aus der Bibliothek aufge-
rufen. Bei fester Größe wird die Funktion geinlinet, aber so, als wäre
die Größe variabel. D.h. auch wenn die Größe ein Vielfaches von 4 ist,
wird am Ende trotzdem noch überprüft, ob noch eine 16- oder 8-Bit-
Schreibaktion erforderlich ist. Den Modulo-4-Check könnte er ja auch
schon zur Compilezeit machen und damit immer optimalen Code generieren.

Im Gegensatz zu -O2 wird bei -Os und bekannter Blockgröße der Modulo-4-
Check sehr wohl gemacht. Das Ergebnis ist eine einfache Schleife
(maximal kurz), die entweder einen 4-, 2- oder 1-Byte-Schreibbefehl
(je nach Modulo-4-Rest) enthält.

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