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

Gast #5182381
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
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
> 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
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
> 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
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
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
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

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.