Verständnis problem bei Pointer auf ein Pointer

Gast #5209151
Lesenswert?

Hallo liebe Forenbesucher,

wie im Betreff schon erwähnt habe ich da ein kleines Verständnis problem 
was POinter auf Pointer betrifft. Ich erkläre es mit einem Beispiel.

1
void test (int * abc){
2

3
   *abc+ = 1;
4
   return 0;
5
}
6

7

8
int main(){
9

10
   int a = 0;
11
   int * ptest = NULL;
12
   ptest =  &a;
13

14
   test(&ptest)  //Da ist mein Verständnisproblem
15
}

Das Beispiel ist ziemlich vereinfacht nur ich verstehe jetzt nicht wie 
ich ein POinter einem Argumentweiter gebe, welcher wiederrum ein POinter 
ist.

Gehört bei der übergabe das kaufmänische UND & dazu oder nicht, weil 
wenn ich es so übergebe bekomme ich die WArrnnung: expected 'int *' but 
argument is of type 'int **'.

Ich hoffe ihr könnt mir da weiterhelfen.

Lg Johannes
Gast #5209154
Lesenswert?

Zunächst einmal ist ptest vom Typ int*. Verwendet man ein & als 
Operator, liefert dieses die Speicheradresse zurück, an dem die Variable 
die gespeichert wird (bei int ist der Typ für diese Speicheradresse 
int*). Beispiel:
a ist vom Typ int. &a liefert einen Pointer auf int also int* (dieser 
Typ speichert die Adresse, an dem ein int steht).
Das ganze musst du jetzt nur logisch fortführen: ptest ist vom Typ int*. 
D.h. &ptest liefert einen Pointer auf int* als int** (dieser Typ 
speichert die Adresse an dem ein Pointer steht, welcher die Adresse 
eines int speichert).

Für dein Beispiel bedeutet dass:
1
void test (int** abc){
2

3
   **abc+ = 1; //zweimal dereferenzieren, weil du a verändern willst, nicht den Pointer inkrementieren
4
   return 0;
5
}
6

7

8
int main(){
9

10
   int a = 0;
11
   int * ptest = NULL;
12
   ptest =  &a;
13

14
   test(&ptest)  //Da ist mein Verständnisproblem
15
}
Gast #5209159
Lesenswert?

Passt vielen dank so habe ich es mir eh auch gedacht aber was passiert 
jetzt, wenn ich in der test - Funktion z.B eine String funktion von 
string.h aufrufe, die als parameter ebenso einen Pointer erwartet:

1
void test (char * x){
2

3
      strcpy (?x?, "defg");  //WAs gehört da jetzt her
4
}
5

6

7
int main(){
8

9
   char buf [] = "abcd"
10

11
   test(buf);
12
}
13
[c]
14

15

16
Ich weiß jetzt nicht was ich da in den Fragezeichen setzen soll, weil wenn ich das so ausführe bekomme ich genau dieselbe Warnug nur diesmal mit char expected 'char *' but argument is of type 'char **'. 
17

18
Das Problem ist ja, dass strcpy als Prototyp so definier ist:
19

20
[c] char *strcpy(char *dest, const char *src)
.

Würde mir es gehen wenn es so definiert wäre:
1
char *strcpy(char *dest, const char **src)

und die  Übergabe an die Funktion müsste ich wahrscheinlich so machen
1
strcpy (&x, "defg");
 oder?

Da das nicht möglich ist, hoffe ich dass ihr mir da vielleicht 
weiterhelfen könnt, wie ich das lösen könnte oder ist das nicht lösbar?

Lg
#5209199
Lesenswert?

Johannes H. schrieb:
> Passt vielen dank so habe ich es mir eh auch gedacht

Schau dir die erste Antwort besser noch mal an, denn

> aber was passiert jetzt, wenn ich in der test - Funktion z.B eine
> String funktion von string.h aufrufe, die als parameter ebenso
> einen Pointer erwartet:
>
>
>
1
> void test (char * x){
2
> 
3
>       strcpy (?x?, "defg");  //WAs gehört da jetzt her
4
> }
5
> 
6
> 
7
> int main(){
8
> 
9
>    char buf [] = "abcd"
10
> 
11
>    test(buf);
12
> }
13
> [c]
14
> 
15
.
16
> Ich weiß jetzt nicht was ich da in den Fragezeichen setzen soll, weil 
17
> wenn ich das so ausführe bekomme ich genau dieselbe Warnug nur diesmal 
18
> mit char expected 'char *' but argument is of type 'char **'.
19
> 
20
> Das Problem ist ja, dass strcpy als Prototyp so definier ist:
21
> 
22
> [c] char *strcpy(char *dest, const char *src)
.
>
> Würde mir es gehen wenn es so definiert wäre:
>
>
1
char *strcpy(char *dest, const char **src)
>
> und die  Übergabe an die Funktion müsste ich wahrscheinlich so machen
>
1
strcpy (&x, "defg");
 oder?


es sieht nicht so aus, als ob das schon sitzt. Zumindest der Transfer zu 
Strings, die durch einen Zeiger auf ihr erstes Zeichen repräsentiert 
werden (sowie ein '\0'-Zeichen am Ende, was bei String-Literalen 
implizit immer dabei ist)
#5209244
Lesenswert?

In deinen Beispielen ist es überhaupt gar nicht nötig Pointer auf 
Pointer zu nutzen. Das macht man nur wenn die Funktion den Wert des 
Pointers verändern soll (also wohin er zeigt) oder man Arrays von 
Pointern hat. Die Daten wohin der Pointer zeigt lassen sich auch so 
verändern. Bezogen auf dein String Beispiel würde man den Code so 
schreiben:
1
void test (char * x){
2
      strcpy (x, "defg");
3
}
4

5
int main(){
6
   char buf [] = "abcd"
7
   test(buf);
8
}
Gast #5209264
Lesenswert?

Mit pointerpointern hat man in der Regel wenig bis garnichts zu tun ... 
Wenn du sowas hast, ist die Chamce groß, dass du einen Denkrehler hast.

Ausnahmen sind 2-Dimensionale Arrays, da geht es quasi nicht anders :)
Gast #5209321
Lesenswert?

Zunächst mal vielen dank für die vielen Antworten. Mir ist schon klar, 
dass das Beispiel auch ohne einem Pointer geht, ich wollte eigentlich 
nur wissen wie man sowas löst weil es ist nicht so, dass sowas selten 
vorkommt...

Also gibt es dafür keine Lösung?
#5209337
Lesenswert?

Johannes H. schrieb:
1
> void test (int * abc){
2
> 
3
>    *abc+ = 1;
4
>    return 0;
5
> }
6
> 
7
> int main(){
8
> 
9
>    int a = 0;
10
>    int * ptest = NULL;
11
>    ptest =  &a;
12
> 
13
>    test(&ptest)  //Da ist mein Verständnisproblem
14
> }
ptest ist vom Typ int*

test erwartet einen Paramter vom Typ int*

Es sind dieselben Typen, also muss da gar nichts gemacht werden.
1
    test(ptest)  // kein Adressoperator
Gast #5209362
Lesenswert?

Ich habs endlich verstanden :)

Also solchen Funktionen wie strcpy kann ich einfache POinter, wie im 
obigen Beispiel angegeben, zuweisen, aber sobald ich einen Pointer auf 
POinter zuweise (sprich **pTtest) bekomme ich die WArnnung:
1
char expected 'char *' but argument is of type 'char **['/c]
2

3
ist ja klar jetzt habe ich ein **ptest und die FUnktion erwartet sich aber nur ein *ptest. 
4

5
Jetzt nur noch zum Verstehen: 
6

7
[c]
8

9
int main (){
10

11
char Buf[10];
12

13
char *pTest = Buf;
14

15
char *pTest1 = pTest;      //ab hier zeigen beide POinter auf das erste Element von Buf oder?
Persönliche Seite #5209468
Lesenswert?

Johannes H. schrieb:
> ist ja klar jetzt habe ich ein **ptest und die FUnktion erwartet sich
> aber nur ein *ptest.

Jau genau ... Deshalb meinte ich vorher, mit ** wird man so gut wie nie 
arbeiten müssen.

Außer es sind 2D-Arrays, aber da würde man dann eher sowas machen:

void foo(char myarray[64][])

dann kann man innerhalb foo auch mit myarray[y][x] arbeiten.

Im Grunde ist aber char myarray[64][] nichts anderes wie ein char**

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