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

Gast #5182381
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
Gast #5182412
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
}
Gast #5182838
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
}
Gast #5182936
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.
Gast #5182966
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.
Gast #5183280
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.
#5184018
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.
Gast #5192655
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren