Forum: Compiler & IDEs [C] Pointer auf Array


von Heiko L. (drcaveman)


Lesenswert?

Hallo!

Ich bräuchte in einer library konstante Werte die von außerhalb der 
library kommen.
Wie viele Werte es werden weiß man allerdings nicht, daher war meine 
Idee, dass eine struct benutzt wird in der die Anzahl der Werte sowie 
ein pointer auf ein array (hier sind die Werte drin) stehen.
Die struct ist dann natürlich extern zu füllen.

Jetzt gibt es für mich zwei Arten den pointer auszuführen:
1. pointer auf Element- Typ des arrays
2. pointer auf array

Das müsste dann so aussehen:
1
int main(void) {
2
  //Das Array
3
  const uint8_t array[2] = { 0, 1 };
4
  //Pointer auf das Array
5
  const uint8_t (*p1_array)[] = &array;
6
  //Pointer auf den Element- Typ
7
  const uint8_t *p2_array = array;
8
  //Benutzen der Pointer
9
  uint8_t a = (*p1_array)[0];
10
  a = p2_array[1];
11
  return ((int) a);
12
}

Damit man außen weiß was los ist wäre der pointer auf das array sinniger 
oder?

Oder noch bessere Lösungen?

Danke fürs Lesen ;)

: Bearbeitet durch User
von pointer (Gast)


Lesenswert?

Es gibt keine Pointer auf Arrays.
vgl. array decay

von Heiko L. (drcaveman)


Lesenswert?

Dann halt pointer auf (speziellen?)pointer.

Aber was ist jetzt besser?

Bei "const uint8_t (*p1_array)[] = &array;" weiß der Compiler doch noch, 
dass p1_array eigentlich ein Array sein soll oder wird das nicht 
irgendwo hinterlegt (da war doch etwas mit sizeof)?

Funktionieren würde doch beides, aber was ist "konformer"?

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Mach einfach einen Pointer mit dem Datentyp eines Array-Elements.

Aufgrund syntaktischen Zuckers kann man einen Pointer (jeden Pointer!) 
hinterher genauso benutzen wie ein Array aus Elementen dieses Typs, und 
aus den selben Gründen kann man auch ein Array genauso verwenden als 
wärs ein Pointer auf das erste Element.

Mach es nicht unnötig komplizierter als es sein muss.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Bernd K. schrieb:
> und aus den selben Gründen kann man auch ein Array genauso verwenden als
> wärs ein Pointer auf das erste Element.

Richtig. Aber man kann aus dem Pointer nicht die Anzahl der 
Arrayelemente bestimmen.

Und deshalb sollte man sich immer angewöhnen, diese separat 
mitzuliefern, sofern nicht ein definierter Wert im Array als Array-Ende 
verwendet werden kann (wie '\0' in Zeichenketten) und das Array nicht 
beschrieben werden soll.

von Sina A. (sinapse)


Lesenswert?

Heiko L. schrieb:
>... = &array;

ich dachte immer das geht nicht... da array nur dem compiler bekannt 
ist. zur laufzeit wird array nirgendwo abgelegt, kann also keine eigene 
adresse &array haben??? was passiert denn da schon wieder?

von (prx) A. K. (prx)


Lesenswert?

Sina A. schrieb:
>>... = &array;
>
> ich dachte immer das geht nicht... da array nur dem compiler bekannt
> ist. zur laufzeit wird array nirgendwo abgelegt, kann also keine eigene
> adresse &array haben??? was passiert denn da schon wieder?

Ein Array hat eine Adresse. Ob die dem Compiler (eigentlich: Linker oder 
Loader) bekannt ist, oder erst zu Laufzeit bestimmt wird weil auf dem 
Stack, ist in diesem Fall egal. Adresse davon bestimmen geht, zuweisen 
auch. Vom Wert her sind array und &array identisch, nur der Typ ist es 
nicht.

Und egal ob das Array nun zerfällt oder stabil ist, int(*)[] ist vom Typ 
her ein Pointer auf ein Array.

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Erst einmal zur Klarstellung:

Ja, C unterscheidet zwischen

- einem Array,

- einem Pointer auf dieses Array und

- einem Pointer auf dessen erstes Element.

Beim Pointer auf ein Array kann man noch unterscheiden, ob dieses Array
eine spezifizierte Größe hat oder nicht.

Ein Pointer auf ein Array mit unspezifizierter Größe (wie p1_array in
Heikos Beispiel) unterscheidet sich von einem Pointer auf das erste
Array-Element im Wesentlichen in den folgenden Punkten:

- Beim Zugriff auf ein Array-Element muss der Pointer vor der
  Indizierung erst dereferenziert werden:
1
    (*p1_pointer)[i]

  Diese Dereferenzierung ist aber rein formaler Natur und schlägt sich
  nicht im erzeugten Binärcode nieder, da ein Pointer auf das Array und
  ein Pointer auf dessen erstes Element zwar unterschidlichen Typs, aber
  numerisch identisch sind.

- Da der Pointer auf einen unvollständigen Typ (nämlich ein Array mit
  unspezifizierter Größe) zeigt, kann die Größe des Arrays nicht mit
  sizeof bestimmt werden:

1
    sizeof *p1_pointer  // Fehler

- Aus demselben Grund kann der Pointer auch nicht indiziert werden:
1
    p1_pointer[i]  // Fehler


Vielleicht drückt in Heikos Beispiel die Verwendung eines Pointers auf
ein Array statt eines Pointers auf dessen erstes Element die Absicht des
Programmierers besser aus. In der Praxis macht das aber niemand so,
allein schon wegen der umständlicheren Schreibweise bei den Array-
Zugriffen.

von Heiko L. (drcaveman)


Lesenswert?

Hallo!
Danke für eure Antworten.

Yalu X. schrieb:
> - Da der Pointer auf einen unvollständigen Typ (nämlich ein Array mit
>   unspezifizierter Größe) zeigt, kann die Größe des Arrays nicht mit
>   sizeof bestimmt werden:
>
>     sizeof *p1_pointer  // Fehler

Da habe ich noch gar nicht drüber nachgedacht.

Yalu X. schrieb:
> In der Praxis macht das aber niemand so,
> allein schon wegen der umständlicheren Schreibweise bei den Array-
> Zugriffen.

Ich denke, dass ich dann auch den "einfachen Pointer" nehme.
Bin ja kein Künstler ;)

Bernd K. schrieb:
> Mach es nicht unnötig komplizierter als es sein muss.

Dafür ist es schon viel zu spät :D

von Rolf M. (rmagnus)


Lesenswert?

Sind diese Werte tatsächlich einfach eine zusammengehörende Reihe von 
Werten eines bestimmten Typs (wie z.B. eine Kennlinie oder so)? Wenn 
nicht, würde ich nicht ein Array, sondern eine Struct nehmen. Man kann 
dann dein einzelnen Elementen sinnvolle Namen geben, sie können auch 
unterschiedliche Typen haben, und das Problem mit der Größe hat sich 
auch gleich erledigt.

von Heiko L. (drcaveman)


Lesenswert?

Hallo!

Es sind Speicheradressen des gleichen Typs, aber man weiß halt nicht wie 
viele es werden.

von Rolf M. (rmagnus)


Lesenswert?

Heiko L. schrieb:
> Es sind Speicheradressen des gleichen Typs, aber man weiß halt nicht wie
> viele es werden.

Was heißt "man weiß nicht"? Beide Seiten müssen sich doch einig darüber 
sein, wieviele Daten da nun drin stehen.

von Heiko L. (drcaveman)


Lesenswert?

Die library weiß nur was sie mit den Daten machen soll, wie viele Daten 
es werden weiß sie erst dann wenn es ihr mitgeteilt wird.

von Mark B. (markbrandis)


Lesenswert?

Heiko L. schrieb:
> Die library weiß nur was sie mit den Daten machen soll, wie viele Daten
> es werden weiß sie erst dann wenn es ihr mitgeteilt wird.

Also gibt es dann wohl einen Parameter wo genau dies (zur Laufzeit) 
drinsteht?

von Heiko L. (drcaveman)


Lesenswert?

Ja, wie ich anfangs schrieb:

"daher war meine
Idee, dass eine struct benutzt wird in der die Anzahl der Werte sowie
ein pointer auf ein array (hier sind die Werte drin) stehen."

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.