Forum: PC-Programmierung Array in Struktur füllen


von Marco Oklitz (Gast)


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

von Johann L. (gjlayde) Benutzerseite


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.

von Marco Oklitz (Gast)


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

von Yalu X. (yalu) (Moderator)


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.

von Johann L. (gjlayde) Benutzerseite


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)))?

von Yalu X. (yalu) (Moderator)


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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?


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.