www.mikrocontroller.net

Forum: Compiler & IDEs Pointer auf Multidimensionales array


Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute!

Ich habe da wohl ein Verständnisproblem! K&R hilft mir nicht weiter, da
mir mein Verständnis sagt, daß ich es genau so mache wie sie das
Beschreiben. :-(

Ich habe:

#define BUFFERS 4
#define BUFFERLENGTH 32

unsigned char RXbufferQueue[BUFFERS][RX_BUFFER_LENGTH];

Eine Funktion:
void initBufferGuard(BufferGuardType *, unsigned char **);

Eine Struct:
typedef struct
BufferGuard
{
  unsigned int  prio[BUFFERS]; /*!< Priority of this buffer (FIFO) */
  unsigned int  lowestPrio;    /*!< The lowest available Priority  */
  unsigned char busy[BUFFERS]; /*!< Buffer 'busy' flag (w/protect)
*/    unsigned char *pBuffer[BUFFERS]; /*!< Pointer to the queue
*/
} BufferGuardType;

Und möchte jetzt folgendes machen:

  initBufferGuard(&RXBufferGuard, RXbufferQueue);

Das liefert mit beim Kompilieren den Fehler:
main.c:46: warning: passing arg 2 of `initBufferGuard' from
incompatible pointer type

Warum?

Gruß,
Patrick...

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich habe jetzt einen Weg gefunden, aber ich glaube, daß das nur ein
Umweg ist:

Ich habe ein Array von Pointern angelegt:
unsigned char *pRXBufferQueue[BUFFERS];

Fülle das Array mit den Pointern der RXBufferQueue:
  for(ctr = 0; ctr < BUFFERS; ctr++)
    pRXBufferQueue[ctr] = RXbufferQueue[ctr];

Und übergebe jetzt pRXBufferQueue an initBufferGuard:
  initBufferGuard(&RXBufferGuard, pRXBufferQueue);

Ich möchte aber doch einfach nur die Adressen des Arrays übergeben,
warum muss ich diese dann vorher in ein Array von Pointern Speichern?
Das ist doch doppelt gemoppelt...

Gruß,
Patrick...

Autor: Heinz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So Hallo...

1.
In der Fkt
  void initBufferGuard(BufferGuardType *, unsigned char **);
wird als zweiter Parameter ein Pointer auf einen Pointer verlangt.
Mit dem Fkt-Aufruf
  initBufferGuard(&RXBufferGuard, RXbufferQueue);
übergist du als zweiten Parameter einen Pointer auf
  unsigned char RXbufferQueue[BUFFERS][RX_BUFFER_LENGTH];
und nicht den Pointer auf den Pointer...
  &RXbufferQueue
ist der Pointer auf den Pointer des Arrays.

2.
Wird ein einfacher Pointer auf zweidimensionales Array erwartet, muss
glaub ich die erste Dimension mit angegeben werden...
also irgendwie so, glaub ich ...
  void initBufferGuard(BufferGuardType *, unsigned char a[BUFFERS][]
);

Gruß Heinz

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Heinz!

'&' hatte ich auch vermutet, erzeugt aber das gleiche Ergebnis!
  initBufferGuard(&RXBufGuard, &RXbufferQueue);

main.c:46: warning: passing arg 2 of `initBufferGuard' from
incompatible pointer type

Wie gesagt: wenn ich die Adressen kopiere, dann gehts, auch ohne die
Größe eines der Arrays anzugeben. Das muss man bei
int main(int argc, char **argv)
ja auch nicht...

Gruß,
Patrick...

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also muss ich tatsächlich immer mit Kopieen der Pointer arbeiten, denn
ich möchte für die zweite Dimension keine Größe angeben müssen (da
diese unterschiedlich sein kann, und mittlerweile sogar ist).

Hab ich das jetzt verstanden?

Gruß,
Patrick...

Autor: Daniel Jelkmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Hier mal ein Codeschnipsel, wie man mehrdimensionale Arrays als
Parameter übergeben kann.

void test(int a[][3])
{
  for (int i=0; i < 2; i++)
    for (int j=0; j < 3; j++)
      printf("%d\n", a[i][j]);
}

int main(void)
{

  int k[2][3] = {{0,1,2},{3,4,5}};
  test(k);
  return 0;
}

Wenn man das auf diese Art und Weise übergibt, dann kann man nur eine
Array-Dimension unspezifiziert lassen, die anderen muss man angeben.

Man könnte das ganze natürlich auch machen und nur einen Pointer
übergeben, der sozusagen auf das erste Array-Element zeigt und dann in
der Funktion selbst entsprechend mit dem Zeiger rumrechnen.
Auch dazu der entsprechende Code:

void test(int *a)
{
  for (int i=0; i < 2; i++)
    for (int j=0; j < 3; j++)
      printf("%d\n", *(a+3*i+j));
}

int main(void)
{
  int k[2][3] = {{0,1,2},{3,4,5}};
  test((int*)k);
  return 0;
}

Das ist aber wohl nicht so schön wie die erste Lösung, zumal man um die
Array-Grenzen nicht drum herum kommt, entweder muss man die Grenzen bei
dem formalen Parameter angeben oder bei der Zeigerarithmetik in der
Funktion kennen.

Ich denke Du könntest die erste Lösung umschreiben, um damit Dein
Problem zu lösen. Viel Erfolg dabei ;)

Bye
 Daniel Jelkmann

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Also: ich habe ein Array aus Pointern angelegt und übergebe dieses
Array  an die Funktion!
Das Funktioniert wunderbar, ich dachte nur, daß es einfacher geht, aber
laut Andreas' Link ist das nicht möglich.

Vielen Dank für eure Vorschläge, die haben mir doch sehr zum
Verständnis verholfen!

Gruß,
Patrick...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.