compiler fehler setzen daten 2d-array

OP #7870284
Lesenswert?

Hallo, ich hab ein Problem, wo ich nicht weiter komme.

1
typedef struct
2
{
3
    uint32_t rows_u32;
4
    uint32_t cols_u32;
5
    uint8_t data_au8[60][60];
6
} graphicData_ts;

das data_au8 soll später noch variable werden (also die Anzahl der Reihen und Spalten).

in der .C habe ich dann

1
static graphicData_ts graphicData_s =
2
{
3
    .rows_u32 = 0,
4
    .cols_u32 = 0,
5
    .data_au8 = {{0}},
6
};
7
... ... ...
8
... ... ...
9
... ... ...
10
... ... ...
11
void graphicInit_v(void)
12
{
13
    graphicData_s.cols_u32 = 60;
14
    graphicData_s.rows_u32 = 60;
15
    graphicData_s.data_au8 = {
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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
18
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
19

20
... ... ...
21
... ... ...
22
... ... ...

Jetzt bekomme ich auf der Zeile graphicData_s.data_au8 = { den Fehler:

1
error: expected expression before '{' token
2
   59 |     graphicData_s.data_au8 = {

aber was ist daran verkehrt? ich hbae genau 60x60 daten (auch != 0)

#7870293
Lesenswert?

Du versuchst hier einem Array einen neuen Wert zuzuweisen, das geht in C so nicht. Man kann nur einzelnen Elementen einen neuen Wert zuweisen - für das ganze Array bräuchte es also eine Schleife.

Ich würde hier allerdings überlegen ob man nicht mit Pointern arbeiten möchte.

Hinweis: Einige C-Compiler betrachten Dateien mit Endung .C (anstatt .c) als C++ Source Code - diese Sprache hat aber signifikante Unterschiede zu C.

OP #7870312
Lesenswert?

Clemens L. schrieb:

Arrays kann man nicht zuweisen, aber Strukturen:

1
void graphicInit_v(void)
2
> {
3
>     graphicData_s = (graphicData_ts){
4
>         .rows_u32 = 60,
5
>         .cols_u32 = 60,
6
>         .data_au8 = {{0, 0}, {0}}
7
>     };
8
> }

Jup, das funktioniert

Jim M. schrieb:

Ich würde hier allerdings überlegen ob man nicht mit Pointern arbeiten möchte.

Ja, das möchte ich später auch machen, zumal es nicht immer die selbe Größe ist.

Jim M. schrieb:

Hinweis: Einige C-Compiler betrachten Dateien mit Endung .C (anstatt .c) als C++ Source Code - diese Sprache hat aber signifikante Unterschiede zu C.

Das ist ein Rechtschreibefehler hier. Die Datei ist .c . Dennoch ein guter Hinweis. Danke :)

#7870316
Lesenswert?

Du könntest "memset(graphicData_s.data_au8, 0, sizeof(uint8_t[graphicData_s.rows_u32][graphicData_s.cols_u32]));" verwenden.

Wenn es sowieso Variabel werden soll, würde ich da erst mal aus dem data_au8 einen Pointer machen.

Unten noch ein Beispiel mit VMTs, die sind bei sowas echt praktisch. (Werden aber vom MSVC nicht unterstützt, aber wer nutzt das schon).

1
#include <stdint.h>
2
#include <stdlib.h>
3
#include <string.h>
4

5
#define graphic_data_vmt(S,N) \
6
  typedef uint8_t N##_row_t[(S).rows_u32]; \
7
  typedef N##_row_t N##_t[(S).cols_u32]; \
8

9
typedef struct {
10
    uint32_t rows_u32;
11
    uint32_t cols_u32;
12
    void* data_au8;
13
} graphicData_ts;
14

15
// Objekte mit static storage duration, also alle globalen, werden per default mit 0 initialisiert
16
// Man kann auch einzelnen Member per designated initializer initialisieren, alle anderen werden dann immer mit 0 initialisiert
17
static graphicData_ts graphicData_s;
18

19
void graphicInit_v(void){
20
  graphicData_s.cols_u32 = 60;
21
  graphicData_s.rows_u32 = 60;
22

23
  { // Scope des VMT einschränken. Nachträgliche Änderungen an graphicData_s.cols_u32 / graphicData_s.rows_u32 werden nicht im Typ übernommen.
24
    graphic_data_vmt(graphicData_s, gd_data); // Definiert VMT Typen, support ist in einigen C Versionsstandards optional!
25
    void* mem = realloc(graphicData_s.data_au8, sizeof(gd_data_t));
26
    // TODO: Prüfen, ob realloc fehlgeschlagen ist
27
    graphicData_s.data_au8 = mem;
28
    memset(graphicData_s.data_au8, 0, sizeof(gd_data_t));
29

30
    // Als Beispiel, ein Rechteck in der Mitte zeichnen, halbe Bildgrösse
31
    gd_data_row_t* gd_data = graphicData_s.data_au8;
32
    for(uint32_t y=graphicData_s.rows_u32*1/4+1; y<graphicData_s.rows_u32*3/4; y++)
33
      for(uint32_t x=graphicData_s.cols_u32*1/4+1; x<graphicData_s.cols_u32*3/4; x++)
34
        gd_data[y][x] = 0xFF;
35
  }
36
}
#7870367
Lesenswert?

Wozu überhaupt initialisieren? Ich zitiere aus 6.7.8 von ISO 8899:1999:

1
If an object that has static storage duration is not initialized explicitly,
2
then:
3
— if it has pointer type, it is initialized to a null pointer;
4
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
5
— if it is an aggregate, every member is initialized (recursively) according to these rules;
6
— if it is a union, the first named member is initialized (recursively) according to these rules.
#7870661
Lesenswert?

Wastl schrieb:

Chandler B. schrieb:

compiler fehler setzen daten 2d-array

Erst mal die Schuld auf den Compiler schieben, der ist fehlerhaft.

Ich habe das interpretiert als "der Compiler meldet einen Fehler", nicht als "der Compiler hat einen Fehler".

Anton schrieb:

Wozu überhaupt initialisieren?

Ja, die explizite 0-Initialisierung ist nicht nötig, schadet aber auch nicht. Die ist hier aber auch gar nicht das Problem.

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