Hallo liebes Forum!
Gibt es eine Möglichkeit, eine Fuktion mit Hilfe einer Variable aufzurufen?
Ich weiß nicht einmal ganau, wie man die Frage richtig stellt, aber ich versuche es mal.
byte = i;
void Programm"i"()
Bisher habe ich das entweder gelöst, in dem ich die Variable an eine Funktion übergeben haben
void Programm(byte i)
und dann mit if() oder case i
Geht das auch, in dem man das "i" in den Programmnamen einbindet?
Ich hoffe das war irgendwie verständlich...
Nein!
Interpretersprachen können das, wenigstens manche.
C++ ist eine Compilersprache. Da gehen alle Funktionsbezeichner bei der Übersetzung dem linken verloren.
Ich empfehle dir ein schönes dickes modernes C++ Grundlagenbuch.
Man kann das natürlich über Pointer (Funktionszeigern) machen
Pointer sind aber nicht so leicht verständlich und leider auch leicht falsch zu verwenden.
Man kann das aber leicher verständlich mit Switch case machen.
Außerdem kann man mehrere Funktionen mit gleichem Namen und verschiedener Anzahl von Parametern haben und je nach anzahl der übergebenen Parameteranzahl wird eine oder die andere Funktion ausgeführt.
ich fürchte du verrennst dich da. Und auch wenn die Antworten bisher gut waren, rate ich dir zeig dein "Problem" in einem vollständigen Sketch - dann bekommst du auch eine Antwort die du gut umsetzen kannst.
< nitpicking>
Das stimmt so nicht ganz. Im Gegenteil erzeugt der C++ Compiler lange "mangled names" mit den Namen, der Aufrufkonvention und den Parameter- und Ergebnistypen bei Funktionen. Damit kann der Linker prüfen, ob alle Aufrufe kompatibel sind und dann erst werden die Namen weggeworfen.
< /nitpicking>
OK, wenn man Compilerlauf und Linken unterscheidet, hast du recht.
Nach dem Linken sind die Bezeichner allerdings weg, so dass ein void Programm"i"() zur Laufzeit nicht möglich ist, nicht möglich sein kann.
Ja, wenn man den Buildprozess nicht als ganzes betrachtet.
... ist ein Makro , die beim (vor dem) Übersetzen gebildet wird, und --wie @paulpaulson zeigt-- den Satz
als unzutreffend brandmarkt. Das sind ähnliche Dinger wie die wie FILEDATE Makros.
Aber ob das eine Lösung für die Originalfrage ist, weiß ich nicht.
Und übrigens: task[Hund]();
übersetzt bei mir nicht, aber task[0]();
schon, und erzeugt wie erwartet die Ausgabe "hund"
Weil so die Funktion
void hund() {
Serial.println(__func__);
}
definiert ist, die schon der Präprozessor in
void hund() {
Serial.println("hund");
}
vorübersetzt. Das ist jetzt nix besonderes, und __func__ macht keine Zauberei, die man nicht auch von Hand hinkriegen könnte.
@combie's Lösung zeigt übrigens, dass man sogar in C++ Funktionen, die gar keinen Namen haben, in einem Array sammeln und und über den Index im Array aufrufen kann.
Hier möchte ich mal auf __PRETTY_FUNCTION__ hinweisen.
Beim debuggen sinnvoll, ins Besondere, wenn man mit Template Funktionen oder sonstigen überladenen Funktionen/Methoden zu tun hat.
Nein, ist es nicht.
In C++ gibt es kein eval() Statement, auch nichts vergleichbares, mit dem man eine Funktion mit einem dynamisch erzeugten Namen aufrufen kann.
z.B. PHP als Interpretersprache kann das.
Hmmm....
Kein Disassembler oder Decompiler ist in der Lage, aus einem fertig gebautem C++ Programm die Funktion/Klassen/Variaben oder was auch immer für Bezeichner zu extrahieren. Eben weil nicht mehr im Maschinencode enthalten.
So ist es auch nicht möglich, zur Laufzeit einen Funktionsbezeichner zusammenzubasteln und die dazugehörige Funktion aufzutreiben.
Zudem:
Das durchnummerieren von Dingen ist eigentlich immer ein Kandidat für Arrays oder andere Container.
Ich gönne dir deine statischen Zeichenketten!
Wenn sie wegoptimiert werden ist mir das auch recht.
Nutzlos sind sie!
Zumindest im Falle das TO sind sie nutzlos.
Die Zeichenketten stecken in der für Daten zuständigen Section und nicht in der Code Section.
Es gibt keine Möglichkeit von der jeweiligen Zeichenkette auf den Ort der Funktion zu schließen.
Einzig in der Funktion ist die Zeichenkette nutzbar.
Danke, sind aber nicht meine, sondern die von @paulpaulson.
Dass man mit dem Namen einer Funktion als Text nicht viel anfangen kann, außer ihn auszudrucken, stimme ich dir völlig zu.
Habe nur --speziell bei dir, lieber @combie-- etwas pedantisch auf deine Aussage reagiert, dass der Name einer Funktion zur Laufzeit nicht mehr vorhanden ist.
Dein Array von namenlosen Funktionen, die also nur über ihren Index im Array erreichbar sind, halte ich für die Lösung, wenn nicht "was willst du eigentlich?" die richtige Antwort ist.
Vielleicht ist dir ja als selbsternannter Pedant aufgefallen, dass ich von Anfang an das Wort Bezeichner verwendet habe. Oder auch nicht aufgefallen...
Leider verwendest du durchgehend das Wort Namen, oder Name.
Hier möchte ich dich darauf hinweisen, dass das, je nach Grad der Pingeligkeit, nicht das gleiche ist, selbst wenn es ähnlich ist. Selbst die gleiche Zeichenfolge.
Über den Bezeichner haben wir Zugriff auf die gewünschte Funktion, zur Compilezeit, können sie nutzen, oder einen Zeiger darauf ermitteln.
Über den Namen, welcher in irgendeinem C-String rum dümpelt, können wir zur Laufzeit nichts ermitteln. Wir können ihn ausgeben und ihn in den Programmquelltexten suchen. Aber wir haben keinen direkten Bezug zur Funktion. Keinen Zeiger, kein Aufruf.
Hier sieht der Combie Pingel den Unterschied zwischen Name und Bezeichner.
Das ist auch der Grund warum ich über Bezeichner rede und geredet habe.
Nein das wurde nicht gebrandmarkt.
Die Bezeichner gehen beim Build Prozess verloren, selbst wenn die Namen in irgendwelche Strings kopiert werden.
Es geht die Möglichkeit verloren, vom Bezeichner aus, die Funktion zu erreichen, zu nutzen.
Der Bezeichner ist der "Anfass", der Name ist Schall und Rauch.
Die Frage ist beantwortet, allerdings habe ich noch nicht alle Lösungen durchprobiert um zu sagen, welche mir an meisten zusagt.
Und das mehrere richtig sind, wird das mit dem markieren schwer....
Und....
Auf den Handy einen anderen Account als auf den PC.
Und ich erinnere mich schon...