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)
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.
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 | }
|
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 :)
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 | }
|
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"
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.
|
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|