Forum: PC-Programmierung compiler fehler setzen daten 2d-array


von Chandler B. (chandler)


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)

von Jim M. (turboj)


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.

von Clemens L. (c_l)


Lesenswert?

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
}

von Chandler B. (chandler)


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

von Daniel A. (daniel-a)


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
}

von Wastl (hartundweichware)


Lesenswert?

Chandler B. schrieb:
> compiler fehler setzen daten 2d-array

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

"einen Fehler in meiner Programmierung kann ich ausschliessen"

von Anton (antang)


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.

von Rolf M. (rmagnus)


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.

: Bearbeitet durch User
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.