BEARBEITEN: Syntaxfehler korrigiert, wie von Chris Lutz gesagt.
Chris Lutz
Ich habe eine Struktur, die eine Deklaration wie diese enthält:
Nein, tust du nicht. Das ist ein Syntaxfehler. Du schaust nach:
void (*functions[256])();
Welches ist ein Array von Funktionszeigern. Beachte das aber void func() ist keine “Funktion, die keine Argumente akzeptiert und nichts zurückgibt”. Es ist eine Funktion, die nicht spezifizierte Zahlen oder Arten von Argumenten akzeptiert und nichts zurückgibt. Wenn Sie “keine Argumente” wollen, brauchen Sie Folgendes:
void (*functions[256])(void);
In C++, void func()tut bedeuten “nimmt keine Argumente”, was einige Verwirrung stiftet (insbesondere da die Funktionalität, die C für void func() ist von zweifelhaftem Wert.)
So oder so, sollten Sie typedef Ihr Funktionszeiger. Dadurch wird der Code unendlich verständlicher und Sie haben nur eine Chance (bei der typedef) um die Syntax falsch zu machen:
Beachten Sie nur, dass memcpy() gefährlich und nicht portierbar ist, da eine Struktur eine beliebige Anzahl von Füllbytes enthalten kann. Wenn Sie memcpy() wie hier gezeigt verwenden, müssen Sie sicherstellen, dass der Compiler kein Padding aktiviert hat. In der Regel durch assert(sizeof(the_struct.functions) == sizeof(functions)) oder ähnliches.
– Ludin
15. März 2011 um 10:33 Uhr
Das ist falsch. sizeof(some_struct) gibt die Größe der Struktur + alle notwendigen Polsterungen zurück. Siehe diese Frage zum Beispiel. Die Verwendung von memcpy oben ist richtig.
– Matte
15. März 2011 um 10:43 Uhr
..und in diesem Fall die memcpy() wird sowieso nicht für Strukturen verwendet – es wird zum Kopieren von einem Array in ein anderes mit identischer Größe verwendet, was in Ordnung ist. Die Tatsache, dass das Zielarray ein Strukturmitglied ist, spielt keine Rolle.
– Café
15. März 2011 um 12:27 Uhr
Das hätte ich wohl anmerken sollen struct ist ein Schlüsselwort, daher ist es falsch, es als Variablennamen zu verwenden, selbst für Beispielcode, der niemals in die Nähe eines Compilers kommen wird.
– Chris Lutz
16. März 2011 um 0:06 Uhr
der Unterschied zwischen func() und func(void) ist nur eine Frage von C++ nicht von C, oder?
– dhein
21. Januar 2016 um 7:48 Uhr
Ich hatte das gleiche Problem, dies ist mein kleines Programm, um die Lösung zu testen. Es sieht ziemlich einfach aus, also dachte ich, ich würde es für zukünftige Besucher teilen.
#include <stdio.h>
int add(int a, int b) {
return a+b;
}
int minus(int a, int b) {
return a-b;
}
int multiply(int a, int b) {
return a*b;
}
typedef int (*f)(int, int); //declare typdef
f func[3] = {&add, &minus, &multiply}; //make array func of type f,
//the pointer to a function
int main() {
int i;
for (i = 0; i < 3; ++i) printf("%d\n", func[i](5, 4));
return 0;
}
TurtleToes
Sie können es dynamisch tun … Hier ist ein kleines Beispiel für ein dynamisches Funktionsarray, das mit malloc zugewiesen wurde …
Mein schlechter … falscher Kontext zu dieser Diskussion … Stattdessen könnten Sie typedef verwenden, um den FOO_FUNC-Typ zu definieren, und dann ein FOO_FUNC-Array erstellen und die Namen als Initialisierer verwenden …
– TurtleToes
15. März 2011 um 12:43 Uhr
Aus der Spitze meines Kopfes und ungetestet.
// create array of pointers to functions
void (*functions[256])(void) = {&function0, &function1, &function2, ..., };
// copy pointers to struct
int i;
for (i = 0; i < 256; i++) struct.functions[i] = functions[i];
BEARBEITEN: Syntaxfehler korrigiert, wie von Chris Lutz gesagt.
Sie könnten dies tun, während Sie Ihre Struct-Instanz deklarieren:
Sie können diese Abkürzung nicht verwenden, um Arrays zu initialisieren, nachdem das Array deklariert wurde: Wenn Sie dies tun müssen, müssen Sie es dynamisch tun (mithilfe einer Schleife, a memcpy oder etwas anderes).
Syntagma
Wenn Sie wollen Post-Initialisieren Sie ein Array mit Formular wie {func1, func2, ...}kann dies auf folgende Weise (mit GCC) erreicht werden: