Forum: Compiler & IDEs Pointer auf Multidimensionales array


von OldBug (Gast)


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...

von OldBug (Gast)


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...

von Heinz (Gast)


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

von OldBug (Gast)


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...

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?


von OldBug (Gast)


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...

von Daniel Jelkmann (Gast)


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

von OldBug (Gast)


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...

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.