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},
...
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.