Funktionsname in Variable speichern und wieder aufrufen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

pillmuncher hat geschrieben: Stimmt. Aber mal angenommen, eine Funktion heißt "Zeitscheibe"? (Tipp: Buchstaben zählen ;-) )

Code: Alles auswählen

struct funcmap {
    char name[10];
    void (*func)(void);
};
...
// define our mapping
    struct funcmap dispatch[CALLS] = {
        {"foo", foo},
        {"bar", bar},
        {"index", bar},
        {"Zeitscheibe", Zeitscheibe}
    };
Gäbe aber zumindest beim Compilieren ein Warning ;-)
Müßte man also statt dem char-Array einen Zeiger auf ein solches nehmen und dann die Länge beim Anlegen dynamisch allocieren?
Außerdem ist die Suche nach der passenden Funktion O(n) (naja, bei drei oder vieren...). Nicht, dass dein Code irgendwie schlecht wäre, man programmiert halt so in C.
Stimmt! Da müßte man also irgend wie hashen, um die Zugriffszeit zu verbessern und näher an ein dict zu kommen. Ich sollte mir mal den C-Quellcode zum dict in Python angucken... vermutlich werde ich ihn wohl aber nicht durchschauen :-D
Aber die Verwendung eines Python-dicts ist im Vergleich dazu die flexiblere, einfachere und fehlertolerantere Lösung, insbesondere deswegen, weil man dict nicht erst selber programmieren muss.
Klar. Ich wollte ja nur mal zeigen, dass es in C nicht unbedingt anders läuft. Letzteres scheint der OP ja super zu verstehen; evtl. hilft es ihm ja auf die Sprünge.
lunar

@Hyperion: Du kannst auch GHashTable nutzen.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

lunar hat geschrieben:@Hyperion: Du kannst auch GHashTable nutzen.
Danke für den Hinweis. Die Glib ist für C ja mittlerweile fast ein Muss. Werde mein Beispiel dahingehend mal anpassen :-)
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Hyperion hat geschrieben:
pillmuncher hat geschrieben: Stimmt. Aber mal angenommen, eine Funktion heißt "Zeitscheibe"? (Tipp: Buchstaben zählen ;-) )

Code: Alles auswählen

struct funcmap {
    char name[10];
    void (*func)(void);
};
Gäbe aber zumindest beim Compilieren ein Warning ;-)
Müßte man also statt dem char-Array einen Zeiger auf ein solches nehmen und dann die Länge beim Anlegen dynamisch allocieren?
Den Aufwand würde ich gar nicht treiben, sondern nur das char-Array vergrößern. Ist ja dein Code, und du weißt ja, wie lang deine Funktionsnamen sind. Vielleicht noch einen Kommentar daneben, damit man's nicht vergisst.
...nur mal zeigen, dass es in C nicht unbedingt anders läuft. Letzteres scheint der OP ja super zu verstehen; evtl. hilft es ihm ja auf die Sprünge.
Vielleicht wollte er auch nur zu erkennen geben, dass er eine "richtige" Programmiersprache kann, statt "bloß" eine "Scriptsprache". Aber wahrscheinlich nicht, denn man soll ja von den Menschen immer nur das beste denken...

Gruß,
Mick.
In specifications, Murphy's Law supersedes Ohm's.
lunar

pillmuncher hat geschrieben:Den Aufwand würde ich gar nicht treiben, sondern nur das char-Array vergrößern. Ist ja dein Code, und du weißt ja, wie lang deine Funktionsnamen sind. Vielleicht noch einen Kommentar daneben, damit man's nicht vergisst.
Gemäß Murphys Law vergisst man es irgendwann aber doch, und den Fehler muss man dann erstmal finden.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Hyperion hat geschrieben:Und was genau ist daran

Code: Alles auswählen

def tolle_funktion(s):
    print "Hipp, Hipp,", s

func_name = tolle_funktion.func_name

# Aufruf dann...

eval(func_name)("Hurra!")
besser / leichter verständlich als

Code: Alles auswählen

def tolle_funktion(s):
    print "Hipp, Hipp", s

func = tolle_funktion
func("Hurra!")
?
Für seine Zwecke nichts... Manchmal habe ich den Hang, die gestellte Frage genau zu beantworten; gelegentlich ist sie ja auch tatsächlich genau so gemeint und sinnvoll. Hier wären aber die dictionary- oder deque-Lösungen, die direkt das Funktionsobject beinhalten, besser.

(Es gibt Ausnahmen, z.B. wenn der User selbstdefinierte Funktionen ausführen lassen können soll, oder wenn Funktionen erst später definiert werden.)

Dem OP möchte ich noch die Regel "eval is evil" mitgeben, auch wenn eval sein konkretes Problem löst.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

pillmuncher hat geschrieben:Außerdem ist die Suche nach der passenden Funktion O(n) (naja, bei drei oder vieren...).
Und noch "eigentlicher" ist sie im Code konstant, da die Anzahl der Funktionen im Voraus veststeht.
mikehydro hat geschrieben:Zum Abschluß nochmal danke an bords0.

Diese Antwort hat mich am besten weitergebracht.
Das was Du hier schreibst funktioniert prima.
Und wenn du jetzt noch verstehst, warum es funktioniert, aber warum man es so auf keinen Fall machen sollte, dann hast du etwas wichtiges gelernt ;-)

Ich kann auch nicht nachvollziehen, warum du Hyperion so angehst. Er ist meiner Meinung nach, so weit es deine (magere) Problembeschreibung zulässt, vernünftig auf deine Fragen eingegangen und hat eine sinnvolle Lösung vorgeschlagen. Wie du das Problem in C gelöst hast/hättest, würde mich schon interessieren. Ich kann mir nämlich gerade keine (ordentliche) Lösung vorstellen, die dieses Problem nicht in ähnlicher Weise angeht.
Das Leben ist wie ein Tennisball.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

EyDu hat geschrieben:
pillmuncher hat geschrieben:Außerdem ist die Suche nach der passenden Funktion O(n) (naja, bei drei oder vieren...).
Und noch "eigentlicher" ist sie im Code konstant, da die Anzahl der Funktionen im Voraus veststeht.

Code: Alles auswählen

for(int i=0; i<CALLS; i++) {
    if(strcmp(dispatch[i].name, argv[1]) == 0) {
        dispatch[i].func();
        return 0;
    }
}
??

Gruß,
Mick.
In specifications, Murphy's Law supersedes Ohm's.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Nur weil dort eine for-Schleife ist, bedeutet dies noch nicht, dass die Suche linear ist.

Code: Alles auswählen

#define CALLS 3

...

// define our mapping
    struct funcmap dispatch[CALLS] = {
        {"foo", foo},
        {"bar", bar},
        {"index", bar}
    };
Das Leben ist wie ein Tennisball.
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Na da hab ich hier ja wieder was verpasst... :shock:

Das eigentliche Problem (nicht jedoch der Tonfall des OP!)
erinnert mich an
http://www.python-forum.de/topic-18873.html
lunar

@EyDu: Wie definierst Du denn eine "lineare Suche"?! Und worauf willst Du mit deinem Quelltextausschnitt hinaus?

Im Allgemeinen jedenfalls ist es völlig ohne Belang, ob die Anzahl der Eingabewerte nun zufälligerweise konstant ist oder nicht. Der gezeigte Suchalgorithmus ist linear, und sofern der gesuchte Name nicht ebenfalls konstant ist, kann der Compiler das auch nicht in einen Zugriff in konstanter Zeit optimieren.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

So, hier mal die Glib-Fassung meines Beispiels:
http://paste.pocoo.org/show/145746/

An der ein oder anderen Stelle ist da sicher Luft für Optimierungen... muss mir diesen ganzen Zeiger-Kram noch mal genauer angucken.
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

In den C-Foren klappt das besser. Ohne Überheblichkeit.
Link? Laut Leonidas soll das zumindest in comp.lang.c (Recht groß?) nicht der Fall sein. Und ich hab noch von keiner nicht-C Version von Ulrich "WTF is this crap" Drepper gehört (ohne damit sagen zu wollen, daß alle C Programmierer so wären).
Müßte man also statt dem char-Array einen Zeiger auf ein solches nehmen und dann die Länge beim Anlegen dynamisch allocieren?
Könnte man. Übringens könntest du noch alle Elemente der Struktur "const" machen. (Wobei ich gar nicht weiß, ob das bei Funktionszeigern klappt).
Ich sollte mir mal den C-Quellcode zum dict in Python angucken... vermutlich werde ich ihn wohl aber nicht durchschauen Very Happy
Wenn du dir einfache C Implementationen für solche Datenstrukturen ansehen willst: Ich habe vor kurzer Zeit diese Seite gefunden. Sieht recht gut aus, hab ich aber selbst nur oberflächlich durchgeschaut :).

Übringens kann man auch für Funktionspointer die "&" Syntax benutzen. C erlaubt für diesen speziellen Fall beide Notationen, einfach nur "func" und "&func".
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

lunar hat geschrieben:@EyDu: Wie definierst Du denn eine "lineare Suche"?! Und worauf willst Du mit deinem Quelltextausschnitt hinaus?

Im Allgemeinen jedenfalls ist es völlig ohne Belang, ob die Anzahl der Eingabewerte nun zufälligerweise konstant ist oder nicht. Der gezeigte Suchalgorithmus ist linear, und sofern der gesuchte Name nicht ebenfalls konstant ist, kann der Compiler das auch nicht in einen Zugriff in konstanter Zeit optimieren.
Ja, der Suchalgorithmus ist linear, das will ich auch gar nicht bestreiten. Mir ging es hier um die konkrete Ausprägung mit drei Elementen. Dafür ist es sehr einfach eine Abschätzung mit konstanter Schranke zu machen.
Das Leben ist wie ein Tennisball.
Antworten