Forum: Compiler & IDEs Zugriff auf mehrdimensionales Array


von Hartmut O. (hardy63)


Lesenswert?

Hallo,

bin gerade dabei, mich in C einzuarbeiten und bin nun beim Thema: Arrays 
und Pointer gelandet. Dazu möchte ich über einen Pointer auf ein 2 
dimensionales Array ( Typ const unsigned char [256][8] ) zugreifen.
Beim compilieren ( AVRStudio 5 )kommen bei unterstehendem Code die 
Meldungen:

subscripted value is neither arry nor pointer
assignment from incompatible pointer type

Was mach ich da falsch?

Schon mal vielen Dank für den Denkanstoss.
Hardy


#include <avr/io.h>
#include "6x8_horizontal_LSB_2.h"

struct font{
    uint8_t width;
    uint8_t height;
    unsigned char *data;
      };

void foo(unsigned char c,struct font font){
    unsigned char w;
    uint8_t i,j;

  for (i=0; i<8; i++)
    {   w = font.data[c][i];    // Fehler
      for (j=0; j<6; j++)
      {   if (w&1)
                asm volatile ("nop");
            else
                asm volatile ("nop");
            w=w>>1;
      }
         }
}


int main(void)
{


  struct font smallFont;
  smallFont.height = FONT6x8_HEIGHT;
  smallFont.width  = FONT6x8_WIDTH;
  smallFont.data   = font6x8;

  while(1)
        {
       foo('A',smallFont);
  }
}
*****************************************************
6x8_horizontal_LSB_2.h

const unsigned char font6x8[256][8]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
...

von Guru (Gast)


Lesenswert?

Hm. Also an der Stelle an der Du im Kommentar "Fehler" geschrieben hast, 
benutzt Du zwar den index operator [] aber in der Struktur steht nur, 
das Data ein Zeiger ist. Der Compiler kann aber nicht wissen, wie die 
Dimensionen des Arrays sind. Wie soll er da die Adresse berechnen?


Du schreibst:
>Dazu möchte ich über einen Pointer auf ein 2
>dimensionales Array ( Typ const unsigned char [256][8] ) zugreifen.

Es kann sein, das Du das möchtest aber durch die Zuweisung in main geht 
die Information über die Dimensionen des Arrays verloren. Du wandelst 
ein zweidimensionales Array von char in einen Zeiger auf char um.

Lies Dir das am besten nochmal in gründlich in einem C Buch durch.

von Karl H. (kbuchegg)


Lesenswert?

Ein 2D Array ist so aufgebaut
(Ich nummeriere die Elemente durch, was es damit auf sich hat, dazu 
später)

          5 Spalten
     0   1   2   3   4

   +---+---+---+---+---+
0  | 0 | 1 | 2 | 3 | 4 |
   +---+---+---+---+---+
1  | 5 | 6 | 7 | 8 | 9 |   3 Zeilen
   +---+---+---+---+---+
2  | 10| 11| 12| 13| 14|
   +---+---+---+---+---+


Wenn du die Nummer des Elements wissen willst, das an der Position Zeile 
1, Spalte 3 sitzt, wie berechnest du diese?

Dazu muss man wissen: wozu brauch ich das überhaupt.
Nun das brauchst du deswegen, weil das Array ja nicht so im Speicher 
liegt, sondern im Speicher alle Elemente einfach hintereinander liegen. 
Der Speicher in einem Computer hat keine Struktur. Alle Elemente liegen 
hintereinander und sind durchnummeriert. So wie die Häuser in einer 
Reihenhaussiedlung auf einer Strassenseite.

 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+- ...
 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| 13|
 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+- ...

Willst du daher auf das Element [1][3] zugreifen, dann muss diese Angabe 
umgerechnet werden in die Elementnummer ab Beginn des Arrays.

Die Umrechnung ist einfach:

  Nummer = Zeile * Anzahl Spalten + Spalte

in konkreten Fall

  Nummer = 1 * 5 + 3

  Nummer = 8

Das Element [1][3] ist also in linearer Form das Element mit der Nummer 
8 gerechnet ab Beginn des Arrays. Kontrolle mit dem ursprünglichen 2D 
Array zeigt: Jawohl das stimmt. Am Schnittpunkt der Zeile 1 und Spalte 3 
ist tatsächlich das Element mit der Nummer 8.

Nur: Dazu musst du die Anzahl der Spalten wissen.
Und genau die hast du (der Compiler) aber nicht, wenn alles was er hat, 
die Angabe

  unsigned char* data;

ist. Damit hat man nur die Anfangsadresse, wo das Array im Speicher 
anfängt. Aber eine Angabe [1][3] kann damit nicht umgerechnet werden in 
eine Arrayposition ab Beginn dieser Speicherposition.

von Guru (Gast)


Lesenswert?

Genau! ;-)

von Hartmut O. (hardy63)


Lesenswert?

Wenn ich es richtig verstanden habe reicht es nicht, einfach die 
Position im Array in Form von [x][y] mitzuteilen sondern die eindeutige 
Postition als
[x*c+i]
Ich hatte angenommen, dass der Compiler aus den Indexangaben die Postion 
selbst berechnet. Die Änderung in:

for (i=0; i<8; i++)
    {   w = font.data[c*8+i];    // Fehler
      for (j=0; j<6; j++)
      {   if (w&1)
                asm volatile ("nop");
            else
                asm volatile ("nop");
            w=w>>1;
      }
         }

läßt den Code ohne Fehler compilieren und funktioniert.

Vielen Dank!
Hardy

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.