Forum: PC-Programmierung Array in Array


von Alex R. (itaxel)


Lesenswert?

Hallo zusammen,

ich möchte mehrere 2d-Arrays in einem Array für einen dynamischen 
Zugriff ablegen.
1
static const int** _fontdesc[] = {
2
  microsoftSansSerif_8ptDescriptors,
3
  microsoftSansSerif_10ptDescriptors
4
};
Die Arrays in _fontdesc sind 2d-Arrays.

Beim compilieren kommt folgende Fehlermeldung:
1
error: cannot convert 'const int (*)[2]' to 'const int**' in initialization


sitze seit Stunden davor und lese und recherchiere und bekomme es nicht 
hin. :(

Mit eindimensionalen Arrays funktioniert es:
1
static const char* _fonttype[] = {
2
  microsoftSansSerif_8,
3
  microsoftSansSerif_10
4
};

Kann mir da jemand weiter helfen?

Gruß Alex

von Daniel A. (daniel-a)


Lesenswert?

Wozu benötigst du denn die zusätzliche indirection? 
microsoftSansSerif_8ptDescriptors hat eben eine weniger.

von nfet (Gast)


Lesenswert?

Das liegt daran, dass Arrays und Zeiger eben nicht ganz dasselbe sind.
1
    static const int** _fontdesc[] = {
2
        (const int**) microsoftSansSerif_8ptDescriptors,
3
        (const int**) microsoftSansSerif_10ptDescriptors
4
    };
Das würde funktionieren. Kommt drauf an, was du dann noch vorhast mit 
_fontdesc. Denn der Zugriff darauf ist jetzt nicht mehr so cool.

Wenn es dir aber reichen würde immer nur einen Zeiger auf das erste 
Element im Array zu speichern, dann ist das viel leichter gemacht und 
sieht auch nicht so seltsam aus.
1
    static const int _fontdesc[] = {
2
        &microsoftSansSerif_8ptDescriptors[0][0],
3
        &microsoftSansSerif_10ptDescriptors[0][0]
4
    };

Ich muss auch zugeben, dass der Zusammenhang zwischen Arrays und Zeigern 
sehr verwirrend ist und ich daher für nichts eine Garantie übernehme.

Wenn es noch jemand besser weiß, dann bin ich daran auch sehr 
interessiert.

von nfet (Gast)


Lesenswert?

1
    int foo0[2][2] = {{1,2},{3,4}};
2
    int foo1[2][2] = {{5,6},{7,8}};
3
4
    int* listeDerArrays[2][2];
5
    *listeDerArrays[0] = (int*)foo0;
6
    *listeDerArrays[1] = (int*)foo1;
7
8
    // Zugriff mit:
9
    listeDerArrays[1][0][1];

Hat mir keine richtige Ruhe gelassen, von daher hier noch eine Lösung

von Daniel A. (daniel-a)


Lesenswert?

Du willst also foo0[1][1] mit listeDerArrays[0][0][3] ansprechen?

von Alex R. (itaxel)


Lesenswert?

nfet schrieb:
> Das liegt daran, dass Arrays und Zeiger eben nicht ganz dasselbe sind.
>     static const int** _fontdesc[] = {
>         (const int**) microsoftSansSerif_8ptDescriptors,
>         (const int**) microsoftSansSerif_10ptDescriptors
>     };
> Das würde funktionieren. Kommt drauf an, was du dann noch vorhast mit
> _fontdesc. Denn der Zugriff darauf ist jetzt nicht mehr so cool

Diese Lösung hat mich schon mal ohne Fehlermeldung weiter gebracht. 
Allerdings bekomme ich beim außlesen ganz andere Werte als enthalten 
sind.

Mein microsoftSansSerif_8ptDescriptors sieht wie folgend aus:
1
static const int microsoftSansSerif_8ptDescriptors[][2] = {
2
   {1, 0},
3
   {4, 12},
4
   {6, 24}
5
}

wenn ich mir dann den ersten Wert ausgeben lasse kommt keine 1 sondern 
148 rauß
1
char myChar = "!";
2
int charASCII = (int)myChar - 33; // charASCCII = 0
3
int fontfamily = 0; // msSansSerif 8pt
4
5
const int charWidth = _fontdesc[fontfamily][charASCII][0];
6
7
Ausgabe von charWidth ist 148 ???

: Bearbeitet durch User
von Alex R. (itaxel)


Lesenswert?

Korrektur:
1
char myChar = "!";

soll natürlich so sein:
1
char myChar = '!';

von Daniel A. (daniel-a)


Lesenswert?

Alex R. schrieb:
> Allerdings bekomme ich beim außlesen ganz andere Werte als enthalten
> sind.

Das liegt am Speicherlayout von mehdimensionalen Arrays und dem falschen 
cast "(const int**) microsoftSansSerif_8ptDescriptors,"

2d Arrays sind im Speicher wie 1d Arrays abgelegt. Der cast kann daraus 
nicht magisch Pointer auf 1d arrays machen, weil diese Pointer nirgens 
gespeichert sind.

Folgende Möglichkeiten:
Array von Pointern auf Mehrdimensionale Arrays: (nearest match)
1
static const int (*_fontdesc[][2])[] = {
2
  microsoftSansSerif_8ptDescriptors
3
};

Möglichkeit 2, compound literal abuse: (worst option)
1
static const int** _fontdesc[] = {
2
  (const int*[]){
3
    microsoftSansSerif_8ptDescriptors[0],
4
    microsoftSansSerif_8ptDescriptors[1],
5
    microsoftSansSerif_8ptDescriptors[2]
6
  }
7
};

Möglichkeit 3, stattdessen structs verwenden: (best option)
1
typedef struct fontCharacterDescriptor {
2
  int charWidth, whatever;
3
} fontCharacterDescriptor_t;
4
5
static const fontCharacterDescriptor_t microsoftSansSerif_8ptDescriptors[] = {
6
   {1, 0},
7
   {4, 12},
8
   {6, 24}
9
};
10
static fontCharacterDescriptor_t (*_fontdesc[])[] = {
11
  microsoftSansSerif_8ptDescriptors
12
};

: Bearbeitet durch User
von Alex R. (itaxel)


Lesenswert?

Hallo Daniel,

vielen Dank für deine Antwort. Das hat mir weiter geholfen.
Hätte nicht gedacht das ich mich an sowas mal aufhängen würde.

Gruß Alex

von Karl H. (kbuchegg)


Lesenswert?

Daniel A. schrieb:

> Möglichkeit 3, stattdessen structs verwenden: (best option)

Was darüber hinaus auch noch öfter weiter hilft, das sind ein paar 
typedefs, mit denen man sich 'Abkürzungen' schafft. Man sieht sie für 
Arrays eher selten, aber sie können auch da recht nützlich sein, um die 
Syntax für darauf aufbauende weitere Datentypen zu entschärfen.

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.