Zeiger auf Funktion in C

Hallo zusammen.

Im folgenden C-Programm verstehe ich einige Sachen nicht. Kann mir das jemand verdeutlichen?

#include "stdio.h"
#include "conio.h"

main()
{
int iarr[10]={2,3,8,1,43,13,22,32,11,7};
float farr[10]={...};
char sarr[10][20]={"Zeus\0","Hera\0","Athena\0","Artemis\0"....};
int i;
int iswap(),fswap(),sswap();

clrscr();
for(i=0;i

1) Die Zeile _int iswap(),fswap(),sswap()_ war mit "Declaration der Funktionspointer" kommentiert. Diese müssen aber doch nach dem Schema _\*iswap()..._ deklariert werden. Oder?

2) Der Aufruf _sort(iarr,iswap)_ . Das ist eine Funktion oder Unterprogramm. Und dieser muss vorher bekannt gegeben worden sein. Ist er aber nicht. Kann das so funktionieren?

3) Generelle Frage. In der Zeile _char sarr[10][20]={"Zeus\0".._ wird ein mehrdimens. Array beschrieben. Wie werden Elemente beim schreiben in ein solches Adressiert? Passiert das hier überhaupt?

Nach dem Hauptprogramm kommt die sort Routine.



    
    sort(void \*v, int (\*swp)())
    {
    int i,m;
    ...}




4) Es werden hier 2 Zeiger _\*v_ und _\*swp_ verwendet die aber vorher nirgendwo deklariert sind. Und mir ist nicht klar wohin die zeigen.


Danke an alle

Hossa :smile:

#include "stdio.h"
#include "conio.h"



> main()

{
int iarr[10]={2,3,8,1,43,13,22,32,11,7};
float farr[10]={...};
char sarr[10][20]={"Zeus\0","Hera\0","Athena\0","Artemis\0"....};
int i;
int iswap(),fswap(),sswap();

clrscr();
for(i=0;i



> 1) Die Zeile _int iswap(),fswap(),sswap()_ war mit  
> "Declaration der Funktionspointer" kommentiert. Diese müssen  
> aber doch nach dem Schema _\*iswap()..._ deklariert  
> werden. Oder?


Was da im Quelltext steht sind Funktions-Prototypen, also Deklarationen von Funktionen, die anderswo definiert werden. Mit Zeigern auf Funktionen hat das nichts zu tun. Ich vermute mal, dass weiter unten im Quelltext die swap-Funktionen definiert sind. Durch die Prototypen werden die Funktionen dem Compiler schon vor ihrer Definition bekannt gemacht, so dass sie innerhalb der main-Funktion verwendet werden können.



> 2) Der Aufruf _sort(iarr,iswap)_ . Das ist eine Funktion  
> oder Unterprogramm. Und dieser muss vorher bekannt gegeben  
> worden sein. Ist er aber nicht. Kann das so funktionieren?


Ähnlich wie die Funktion "iswap" ist auch die Funktion "sort" nirgendwo sichtbar definiert. Daher muss zumindest die Deklaration mittels #include in den Quelltext eingebunden werden. Daher kann das so nicht funktionieren, weder die Swap-Funktionen noch die Funktion sort sind in oder in deklariert.



> 3) Generelle Frage. In der Zeile _char  
> sarr[10][20]={"Zeus\0".._ wird ein mehrdimens. Array  
> beschrieben. Wie werden Elemente beim schreiben in ein solches  
> Adressiert? Passiert das hier überhaupt?


In C wird sarr als lineares Array mit 231 Elementen behandelt. Der Compiler nummeriert sie sozusagen linear durch und verwandelt einen Ausdruck der Form sarr[i][k] intern in sarr[21\*i+k]. Beim Befüllen läuft sozusagen der rechte Index von 0 bis 20 hoch. Dann springt der linke Index um 1 nach oben und der rechte beginnt wieder bei 0.



> Nach dem Hauptprogramm kommt die sort Routine.


Das Problem ist, dass die sort-Routine aufgerufen wird, bevor der Compiler weiß, was der Bezeichner sort bedeutet. Entweder muss die sort-Routine daher vor die main-Funktion gesetzt werden oder es muss ein Prototyp von sort vor der ersten Verwendung angegeben werden.



    
    sort(void \*v, int (\*swp)())
    {
    int i,m;
    ...}






> 4) Es werden hier 2 Zeiger _\*v_ und _\*swp_ verwendet  
> die aber vorher nirgendwo deklariert sind. Und mir ist nicht  
> klar wohin die zeigen.


Diese Zeiger werden durch die Parameterdeklaration definiert. Der Compiler weiß durch die Funktionsdefinition, was die Bezeichner v und swp sein sollen. Diese Bezeichner werden beim Aufruf der Funktion durch die entsprechenen Parameter befüllt.

sort(iarr,iswap); ==\> v=iarr, swp=iswap

Tatsächlich werden alle Parameter einer Funktion als interne Variablen der Funktion behandelt, die auf dem Stack angelegt werden.

Viele Grüße

Was da im Quelltext steht sind Funktions-Prototypen

Muss der Prototyp einer Funktion nicht die komplette erste Zeile der Funktion enthalten?
Das ist hier nicht der Fall. Die erste Zeile der Funktion iswap z,B. lautet

int iswap(int \*v,int i, int j, int m)

Und wenn es kein Prototyp ist, sondern wirklich, wie in der Quelle kommentiert, Deklaration der Funktionspointer, dann kann es nur falsch sein?

Der Compiler weiß durch die Funktionsdefinition, was die
Bezeichner v und swp sein sollen. Diese Bezeichner werden beim
Aufruf der Funktion durch die entsprechenen Parameter befüllt.

sort(iarr,iswap); ==> v=iarr, swp=iswap

Das war neu für mich.

Danke Stefan, deine Antwort hat mich weitergebracht.

Hossa :smile:

Muss der Prototyp einer Funktion nicht die komplette erste
Zeile der Funktion enthalten?

Doch, muss es. Man kann lediglich die Namen der Parameter weglassen, nicht jedoch deren Datentyp.

Das ist hier nicht der Fall. Die erste Zeile der Funktion
iswap z,B. lautet

int iswap(int \*v,int i, int j, int m)

Dann ist das in der main-Funktion definitiv falsch. Die Deklaration eines Zeigers fp_iswap auf die Funktion iswap sieht so aus:

int (*fp_iswap)(int*, int, int, int);

Dann kannst du die Adresse von iswap an diesen Zeiger zuweisen:

fp_iswap= &iswap;

wobei der Adress-Operator „&“ auch weggelassen werden kann.

Viele Grüße