Wie sollte ich ein Array von Funktionszeigern in C verwenden?
Wie kann ich sie initialisieren?
Wie sollte ich ein Array von Funktionszeigern in C verwenden?
Wie kann ich sie initialisieren?
VonC
Sie haben ein gutes Beispiel hier (Array von Funktionszeigern)mit dem Syntax detailliert.
int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);
int (*p[4]) (int x, int y);
int main(void)
{
int result;
int i, j, op;
p[0] = sum; /* address of sum() */
p[1] = subtract; /* address of subtract() */
p[2] = mul; /* address of mul() */
p[3] = div; /* address of div() */
[...]
So rufen Sie einen dieser Funktionszeiger auf:
result = (*p[op]) (i, j); // op being the index of one of the four functions
Gute Antwort – Sie sollten sie jedoch erweitern, um zu zeigen, wie eine der Funktionen aufgerufen wird.
– Jonathan Leffler
31. Oktober 2008 um 19:30 Uhr
@crucifiedsoul “the C Programming Language”, geschrieben von Brian Kernighan und Dennis Ritchie? Es könnte sein, aber ich hatte es nicht als Referenz, als ich vor dreieinhalb Jahren die Antwort schrieb. Ich weiß es nicht.
– VonC
30. März 2012 um 1:51 Uhr
Ich möchte hinzufügen, dass Sie p mit initialisieren können (*p[4]) (int, int) {sum,substract,mul,div}
– Jiggunjer
7. Juli 2015 um 8:04 Uhr
@VonC: tolle Antwort. +1 für die Links.
– Destruktor
9. Juli 2015 um 17:04 Uhr
@WilliamMartens Gern geschehen. Ich bin immer überrascht, wenn ein Link, den ich vor über 12 Jahren benutzt habe, immer noch funktioniert!
– VonC
17. Februar 2021 um 9:33 Uhr
Manoj Zweifel
Die obigen Antworten können Ihnen helfen, aber Sie möchten vielleicht auch wissen, wie man ein Array von Funktionszeigern verwendet.
void fun1()
{
}
void fun2()
{
}
void fun3()
{
}
void (*func_ptr[3])() = {fun1, fun2, fun3};
main()
{
int option;
printf("\nEnter function number you want");
printf("\nYou should not enter other than 0 , 1, 2"); /* because we have only 3 functions */
scanf("%d",&option);
if((option>=0)&&(option<=2))
{
(*func_ptr[option])();
}
return 0;
}
Sie können nur die Adressen von Funktionen mit demselben Rückgabetyp und denselben Argumenttypen und derselben Anzahl von Argumenten einem einzigen Funktionszeigerarray zuweisen.
Sie können auch Argumente wie unten übergeben, wenn alle oben genannten Funktionen die gleiche Anzahl von Argumenten des gleichen Typs haben.
(*func_ptr[option])(argu1);
Hinweis: Hier im Array beginnt die Nummerierung der Funktionszeiger wie bei allgemeinen Arrays bei 0. Also im obigen Beispiel fun1
kann aufgerufen werden, wenn Option=0, fun2
kann aufgerufen werden, wenn Option=1 und fun3
kann aufgerufen werden, wenn Option=2.
Auch für diese kleine Demo sollten Sie den Eingabewert überprüfen, da der Code auf einen Neuling abzielt … 🙂
– Philho
31. Oktober 2008 um 6:53 Uhr
Vergessen Sie nicht #include
– www-0av-Com
31. Januar um 13:22 Uhr
Rasmi Ranjan Nayak
So können Sie es verwenden:
#ifndef NEW_FUN_H_
#define NEW_FUN_H_
#include <stdio.h>
typedef int speed;
speed fun(int x);
enum fp {
f1, f2, f3, f4, f5
};
void F1();
void F2();
void F3();
void F4();
void F5();
#endif
#include "New_Fun.h"
speed fun(int x)
{
int Vel;
Vel = x;
return Vel;
}
void F1()
{
printf("From F1\n");
}
void F2()
{
printf("From F2\n");
}
void F3()
{
printf("From F3\n");
}
void F4()
{
printf("From F4\n");
}
void F5()
{
printf("From F5\n");
}
#include <stdio.h>
#include "New_Fun.h"
int main()
{
int (*F_P)(int y);
void (*F_A[5])() = { F1, F2, F3, F4, F5 }; // if it is int the pointer incompatible is bound to happen
int xyz, i;
printf("Hello Function Pointer!\n");
F_P = fun;
xyz = F_P(5);
printf("The Value is %d\n", xyz);
//(*F_A[5]) = { F1, F2, F3, F4, F5 };
for (i = 0; i < 5; i++)
{
F_A[i]();
}
printf("\n\n");
F_A[f1]();
F_A[f2]();
F_A[f3]();
F_A[f4]();
return 0;
}
Ich hoffe, das hilft zum Verständnis Function Pointer.
Zeile 15 von Main.c sollte für (i = 0; i < 5; i++) stehen, richtig?
– Benutzer3116936
14. Januar 2017 um 3:40 Uhr
Warum haben Sie den fp-Enumerator deklariert?
– Pfeil
18. September 2017 um 12:50 Uhr
@Arrrow: Ich glaube, ich habe einen Teil des Legacy-Codes gesehen, wo sie es auf diese Weise gemacht haben … Und es sieht sehr schön aus. Einfach entfernen f1, f2 ...
und anstelle von dann ‘writefile, readfromfile …’ eingeben … es wird redabler
– Rasmi Ranjan Nayak
13. November 2017 um 21:06 Uhr
Diese “Antwort” ist eher ein Nachtrag zur Antwort von VonC; Beachten Sie nur, dass die Syntax über eine Typedef vereinfacht werden kann und die Aggregatinitialisierung verwendet werden kann:
typedef int FUNC(int, int);
FUNC sum, subtract, mul, div;
FUNC *p[4] = { sum, subtract, mul, div };
int main(void)
{
int result;
int i = 2, j = 3, op = 2; // 2: mul
result = p[op](i, j); // = 6
}
// maybe even in another file
int sum(int a, int b) { return a+b; }
int subtract(int a, int b) { return a-b; }
int mul(int a, int b) { return a*b; }
int div(int a, int b) { return a/b; }
Alex Hajnal
Hier ist ein einfacheres Beispiel, wie es geht:
jump_table.c
int func1(int arg) { return arg + 1; }
int func2(int arg) { return arg + 2; }
int func3(int arg) { return arg + 3; }
int func4(int arg) { return arg + 4; }
int func5(int arg) { return arg + 5; }
int func6(int arg) { return arg + 6; }
int func7(int arg) { return arg + 7; }
int func8(int arg) { return arg + 8; }
int func9(int arg) { return arg + 9; }
int func10(int arg) { return arg + 10; }
int (*jump_table[10])(int) = { func1, func2, func3, func4, func5,
func6, func7, func8, func9, func10 };
int main(void) {
int index = 2;
int argument = 42;
int result = (*jump_table[index])(argument);
// result is 45
}
Alle im Array gespeicherten Funktionen müssen die gleiche Signatur haben. Das bedeutet einfach, dass sie denselben Typ zurückgeben müssen (z int
) und haben die gleichen Argumente (eine einzige int
im Beispiel oben).
In C++ können Sie dasselbe mit tun statisch Klassenmethoden (aber keine Instanzmethoden). Sie könnten zum Beispiel verwenden MyClass::myStaticMethod
im Array oben, aber nicht MyClass::myInstanceMethod
Noch instance.myInstanceMethod
:
class MyClass {
public:
static int myStaticMethod(int foo) { return foo + 17; }
int myInstanceMethod(int bar) { return bar + 17; }
}
MyClass instance;
Jonathan Leffler
Oh, es gibt Unmengen von Beispielen. Schauen Sie sich einfach irgendetwas in glib oder gtk an. Dort können Sie die Arbeit von Funktionszeigern in Arbeit sehen.
Hier zB die Initialisierung des gtk_button Zeugs.
static void
gtk_button_class_init (GtkButtonClass *klass)
{
GObjectClass *gobject_class;
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
gobject_class = G_OBJECT_CLASS (klass);
object_class = (GtkObjectClass*) klass;
widget_class = (GtkWidgetClass*) klass;
container_class = (GtkContainerClass*) klass;
gobject_class->constructor = gtk_button_constructor;
gobject_class->set_property = gtk_button_set_property;
gobject_class->get_property = gtk_button_get_property;
Und in gtkobject.h finden Sie die folgenden Deklarationen:
struct _GtkObjectClass
{
GInitiallyUnownedClass parent_class;
/* Non overridable class methods to set and get per class arguments */
void (*set_arg) (GtkObject *object,
GtkArg *arg,
guint arg_id);
void (*get_arg) (GtkObject *object,
GtkArg *arg,
guint arg_id);
/* Default signal handler for the ::destroy signal, which is
* invoked to request that references to the widget be dropped.
* If an object class overrides destroy() in order to perform class
* specific destruction then it must still invoke its superclass'
* implementation of the method after it is finished with its
* own cleanup. (See gtk_widget_real_destroy() for an example of
* how to do this).
*/
void (*destroy) (GtkObject *object);
};
Das Zeug (*set_arg) ist ein Zeiger auf eine Funktion und dieser kann zB eine andere Implementierung in einer abgeleiteten Klasse zugewiesen werden.
Oft sieht man so etwas
struct function_table {
char *name;
void (*some_fun)(int arg1, double arg2);
};
void function1(int arg1, double arg2)....
struct function_table my_table [] = {
{"function1", function1},
...
So können Sie über den Namen in die Tabelle greifen und die “zugehörige” Funktion aufrufen.
Oder vielleicht verwenden Sie eine Hash-Tabelle, in die Sie die Funktion einfügen und sie “nach Namen” nennen.
Grüße
Friedrich
Peter Hirt
Kann es so verwenden:
//! Define:
#define F_NUM 3
int (*pFunctions[F_NUM])(void * arg);
//! Initialise:
int someFunction(void * arg) {
int a= *((int*)arg);
return a*a;
}
pFunctions[0]= someFunction;
//! Use:
int someMethod(int idx, void * arg, int * result) {
int done= 0;
if (idx < F_NUM && pFunctions[idx] != NULL) {
*result= pFunctions[idx](arg);
done= 1;
}
return done;
}
int x= 2;
int z= 0;
someMethod(0, (void*)&x, &z);
assert(z == 4);