Forum: Compiler & IDEs Pointer auf Funktion in C


von christian (Gast)


Lesenswert?

Hallo,

stehe etwas auf dem Schlauch(in C).Wie kann ich aus der main
heraus mittels eines Zeigers point auf die Funktion fkt(),
alle Elemente in arr auslesen?

So wie unten aufgeführt, gibt printf nur 0,1,2,3,4,5,...
Mittels *(point++) müsste doch der Zeiger auf das nä.
Arrayelement zeigen.(die Klammer hat doch höhere Bindung als *)

Code:

int *fkt(){
         int arr[]={0,11,12,13,14,15,16,17};
         int *p;
         p=arr[0];
         return(p);
}
main(){
        int i;
        int (*point)();

        point=fkt();
        for(i=0;i<8;i++)
               printf("alle arr[] Elemente sind: %d\n",*(point++));
}

Danke für jede Hilfe!
Mfg
Christian

von Florian P. (db1pf)


Lesenswert?

Böse!
In der Funktion fkt() wird das Array arr[] auf dem Stack angelegt. Du 
gibst nun einen Pointer auf das Array zurück. Wenn die Funktion 
verlassen wird, ist die Variable arr[] jedoch nicht mehr gültig. Das 
heißt, der Speicherbereich könnte durch eine andere Funktion/Programm 
überschrieben werden! Das würde dann auch die unerwartete Ausgabe 
erklären.

Grüße,
Florian

von atat (Gast)


Lesenswert?

Für sowas nutzt man imho Strukturen, wenn du trotzdem den Zeiger einer 
Funktion brauchst, baue einen void* in die Struktur, damit kannst du 
dann auf Funktionen verweisen. Wobei bei deinem Stück Code anscheinend 
kein Funktionszeiger benötigt wird.
Ich glaube auch, dass du nochmal im Internet nach "Zeiger auf 
Funktionen" suchen möchtest. ;-)

von christian (Gast)


Lesenswert?

Ich kann aber mit z.b "p=arr[2]" (in der Funktion) und dann
mit (in main):

"printf("das dritte Element heißt: %d\n",*(point));"

jedes beliebige Element auslesen.
D.h. point greift auf die richtige Adresse zu.
Ich möchte aber alle Elemente auslesen lassen(nicht nur einzelne).

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du vermengst da zwei Dinge. Einerseits verwendest Du mit point einen 
Funktionspointer, das ist ein Pointer, der auf eine Funktion zeigt.
Der ist soweit richtig deklariert, auch wenn Du bei der Zuweisung die 
Klammern weglassen solltest.

Statt point = fkt(); solltest Du point = fkt; schreiben).

Andererseits aber verwendest Du diesen Pointer für Pointerarithmetik 
(was absolut unzulässig ist), und willst aber eigentlich auf in der 
Funktion definierte automatische, also nur zur Laufzeit der Funktion 
existierende Variablen zugreifen.

Das geht ganz gründlich in die Hose.

Einerseits ist für das, was Du da versuchst, gar kein Funktionspointer 
erforderlich, ein einfacher int-Pointer würde genügen:
1
int *fkt(){
2
         int arr[]={0,11,12,13,14,15,16,17};
3
         int *p;
4
         p=arr[0];
5
         return(p);
6
}
7
main(){
8
        int i;
9
        int *point;
10
11
        point=fkt();
12
        for(i=0;i<8;i++)
13
               printf("alle arr[] Elemente sind: %d\n",*(point++));
14
}

Aber auch dann schlägt die Angelegenheit wegen Deines zweiten 
konzeptionellen Fehlers fehl, denn die in fkt() definierte Variable 
arr[] existiert nur innerhalb der Funktion fkt().

In Funktionen definierte Variablen werden auf dem Stack angelegt, 
belegen also nur zur Laufzeit der Funktion Speicher.

Mit dem Schlüsselwort static lässt sich das umgehen:
1
int *fkt(){
2
         static int arr[]={0,11,12,13,14,15,16,17};
3
         int *p;
4
         p=arr;
5
         return(p);
6
}
7
main(){
8
        int i;
9
        int *point;
10
11
        point=fkt();
12
        for(i=0;i<8;i++)
13
               printf("alle arr[] Elemente sind: %d\n",*(point++));
14
}

Davon abgesehen weist Du in fkt() dem Pointer p nicht die Adresse des 
ersten Arrayelementes zu, sondern dessen Wert.
Statt
1
p = arr[0];
solltest Du also schreiben
1
p = &arr[0];
oder vereinfacht
1
p = arr;

Spätestens damit aber ist p recht nutzlos geworden, Du kannst auch 
schreiben
1
int *fkt(){
2
         static int arr[]={0,11,12,13,14,15,16,17};
3
         return(arr);
4
}

von Florian P. (db1pf)


Lesenswert?

Den Pointer auf eine Funktion brauchst du nicht. Die Funktion fkt() gibt 
dir einen Pointer auf ein Int! zurück. Also brauche wir um das Ergebnis 
zu speichern auch einen Int-Zeiger.

int *fkt(){
         static int arr[]={0,11,12,13,14,15,16,17};
         int *p;
         p=&arr[0];
         return(p);
}

main(){
        int i;
        int *p;

        p=fkt();
        for(i=0;i<8;i++)
               printf("alle arr[] Elemente sind: %d\n",*p++);
}

Habs jetzt nicht ausprobiert, müsste aber so gehen.

Grüße,
Florian


Edit:
...zu spät, nur zweiter...

von christian (Gast)


Lesenswert?

Danke Danke Leute,

weiß jetzt Bescheid.

Mfg
Christian

von Jörg P. (zwiebackfraeser)


Lesenswert?

Hallo Christian,
bei dir wird das erste Element aus arr zurückgegeben, also 0 und dann 
wird von 0 bis Schleifenindex hochgezählt.
Versuchs mal hiermit:
1
int *fkt( int index)
2
{
3
         int arr[]={0,11,12,13,14,15,16,17};
4
         return(arr[index]);
5
}
6
main()
7
{
8
        int i;
9
               
10
        for(i=0;i<8;i++)
11
               printf("alle arr[] Elemente sind: %d\n",fkt (i));
12
}

Gruß Jörg

von Florian P. (db1pf)


Lesenswert?

@Jörg:
Dann musst du aber den * bei fkt() weg lassen. Du willst ja das Element 
und nicht einen Pointer darauf zurück geben.

Grüße,
Florian

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.