mikrocontroller.net

Forum: Compiler & IDEs Pointer auf Funktion in C


Autor: christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Florian Pfanner (db1pf)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: atat (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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. ;-)

Autor: christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
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++));
}

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:
int *fkt(){
         static int arr[]={0,11,12,13,14,15,16,17};
         int *p;
         p=arr;
         return(p);
}
main(){
        int i;
        int *point;

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

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

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

Autor: Florian Pfanner (db1pf)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Danke Leute,

weiß jetzt Bescheid.

Mfg
Christian

Autor: Jörg P. (zwiebackfraeser)
Datum:

Bewertung
0 lesenswert
nicht 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:
int *fkt( int index)
{
         int arr[]={0,11,12,13,14,15,16,17};
         return(arr[index]);
}
main()
{
        int i;
               
        for(i=0;i<8;i++)
               printf("alle arr[] Elemente sind: %d\n",fkt (i));
}


Gruß Jörg

Autor: Florian Pfanner (db1pf)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.