Forum: PC-Programmierung C-Funktion: externen Pointer verändern -> Pointer auf Pointer notwendig?


von Ralf (Gast)


Lesenswert?

Hallo,

ich habe eine Verständnisfrage zu Pointern: wenn ich mit einer 
C-Funktion einen Pointer außerhalb der Funktion ändern möchte, dann darf 
die C-Funktion nicht einen "einfachen" Pointer als Parameter erwarten, 
sondern es muss ein Pointer auf einen Pointer sein, ist das korrekt?

Also anstatt:
1
uint8_t Arr_A[8];
2
uint8_t Arr_B[8];
3
uint8_t *PtrArr = Arr_A[0];
4
5
void A(uint8_t *Ptr) {
6
  Ptr = Arr_B[0];
7
}
8
9
int main(void) {
10
  A(PtrArr);
11
}
muss es lauten:
1
void A(uint8_t **Ptr) {  //Pointer auf Pointer
2
  *Ptr = Arr_B[0];
3
}
4
5
int main(void) {
6
  A(&PtrArr);               //Adresse des Pointers übergeben
7
}
weil der Pointer als Parameter selbst nur by-value übergeben wird. Im 
ersten Codeschnipsel würde demnach nur innerhalb der Funktion auf das 
zweite Array verwiesen, PtrArr selbst würde nicht geändert. Stimmt das 
so?

Wenn statt auf Arrays auf Structs verwiesen wird, deren Member selbst 
Pointer auf Arrays sind, würde es aber mit einfachen Pointern 
funktionieren, richtig?

Ralf

von Heinz (Gast)


Lesenswert?

Ja,
 aber Arr_B[0] ist kein Pointer sondern ein uint8_t, in dem Fall der 
Wert des 0ten Eintrags des Arrays Arr_B.

Lg

von PuhBer (Gast)


Lesenswert?

Ralf schrieb:
> uint8_t Arr_A[8];
> uint8_t Arr_B[8];
> uint8_t *PtrArr = Arr_A[0];
>
> void A(uint8_t *Ptr) {
>   Ptr = Arr_B[0];
> }
>
> int main(void) {
>   A(PtrArr);
> }
1
void A(uint8_t *Ptr, uint8_t *otherPtr) {
2
  Ptr[0] = *(otherPtr + 3);
3
}
4
5
uint8_t Arr_A[8];
6
uint8_t Arr_B[8];
7
8
int main(void) {
9
  A(&(Arr_A[2], Arr_B);
10
}

von Noch einer (Gast)


Lesenswert?

> void A(uint8_t *Ptr, uint8_t *otherPtr) ???

Warum so kompliziert? Der Vorschlag von Heinz reicht doch vollkommen 
aus.
1
uint8_t Arr_A[8];
2
uint8_t Arr_B[8];
3
uint8_t *PtrArr = Arr_A;
4
5
void A(uint8_t **Ptr) {  //Pointer auf Pointer
6
  *Ptr = Arr_B;
7
}
8
9
int main(void) {
10
  Arr_B[0] = 42;
11
  A(&PtrArr);               //Adresse des Pointers übergeben
12
  printf("%d\n", (int) PtrArr[0]);
13
}

von PuhBer (Gast)


Lesenswert?

Noch einer schrieb:
> Warum so kompliziert?
Noch einer schrieb:
> void A(uint8_t **Ptr) {  //Pointer auf Pointer
>   *Ptr = Arr_B;

frage ich mich hier auch.

Da alle Variablen global sind, braucht es überhaupt keinen Parameter in 
der Funktion. ;-)
Wenn ich Inhalte des Array in der Funktion verändern möchte, brauche ich 
keinen zusätzlichen Pointer darauf. Also **Ptr ist bei der 
Aufgabenstellung *Ptr = Arr_B[0] blödsinn.

von BlaBla (Gast)


Lesenswert?

PuhBer schrieb:
> blödsinn

Erstens schreibt man Blödsinn groß,
zweitens sind solche Worte unangemessen.

von Noch einer (Gast)


Lesenswert?

> Aufgabenstellung *Ptr = Arr_B[0]

Was ist die Aufgabenstellung?

Möchtest du den Inhalt des Arrays in der Funktion verändern?
Oder soll nach dem Funktionsaufruf das PtrArr auf ein anderes Array 
zeigen?

> Da alle Variablen global sind...

Psst! Sonst bekommen wir bei der nächsten Frage ein sinnvolles, aber 
unüberschaubar grosses Beispiel.

von PuhBer (Gast)


Lesenswert?

Ich.moechte gar nichts verändern. Das steht so im Ausgangsposting.

von c-hater (Gast)


Lesenswert?

Ralf schrieb:

> ich habe eine Verständnisfrage zu Pointern: wenn ich mit einer
> C-Funktion einen Pointer außerhalb der Funktion ändern möchte, dann darf
> die C-Funktion nicht einen "einfachen" Pointer als Parameter erwarten,
> sondern es muss ein Pointer auf einen Pointer sein, ist das korrekt?

Nicht unbedingt. C erlaubt ja fast jeden Schmutz. Wenn man es aber so 
nutzt, dass man wenigstens die geringe Sicherheit des nur angedeuteten 
Typsystems nicht verletzt: Ja, dann ist es so, dann sollte ein Zeiger 
auf einen Zeiger übergeben werden.

von Jobst Q. (joquis)


Lesenswert?

Ralf schrieb:
> uint8_t *PtrArr = Arr_A[0];

Das ist großer Murks in mehrfacher Hinsicht.

Zum Einen, weil du damit einen Pointer mit einem Inhalt (uint8_t)
initialisieren willst. Korrekter wäre da:

uint8_t *PtrArr = Arr_A;

denn ein Array ist in C identisch mit einem Pointer auf das erste 
Element.

Aber auch das ist schlechter Stil, einen veränderlichen Pointer mit der 
Deklaration schon zu initialisieren. Denn es sollte vor einem Zugriff 
über einen Pointer klar sein, wohin dieser zeigt. Das ist mit einer 
expliziten Zuweisung im Programmablauf besser gewährleistet und besser 
sichtbar als in der statischen Deklaration.

von Peter D. (peda)


Lesenswert?

Ralf schrieb:
> wenn ich mit einer
> C-Funktion einen Pointer außerhalb der Funktion ändern möchte, dann darf
> die C-Funktion nicht einen "einfachen" Pointer als Parameter erwarten

Doch, Du kannst auch einen Pointer zurückgeben, wird z.B. in der 
string.h sehr gerne gemacht.

von MaWin (Gast)


Lesenswert?

Jobst Q. schrieb:
> denn ein Array ist in C identisch mit einem Pointer auf das erste
> Element.

Das ist nicht wahr. Identisch sind sie nicht. Es hängt vom Kontext ab, 
ob decay-to-pointer stattfindet.
1
#include <stdio.h>
2
int main(void)
3
{
4
        int a[10];
5
        printf("%d %d\n", sizeof(a), sizeof(&a[0]));
6
}

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.