Funktionszeiger

Gast #1901667
Lesenswert?

Hallo zusammen,

ich möchte Funktionsaufrufe von dem Wert einer Variable abhängig machen, 
um mir lange if-Abfragen zu ersparen.
Hat die Variable X den Wert 0, soll Func1 aufgerufen, hat sie den Wert 
1, soll Func2 aufgerufen werden, etc.

Wie kann ich das am besten anstellen?


Viele Grüße

Dennis
#1901672
Lesenswert?

Dennis schrieb:
> Hallo zusammen,
>
> ich möchte Funktionsaufrufe von dem Wert einer Variable abhängig machen,
> um mir lange if-Abfragen zu ersparen.
> Hat die Variable X den Wert 0, soll Func1 aufgerufen, hat sie den Wert
> 1, soll Func2 aufgerufen werden, etc.
>
> Wie kann ich das am besten anstellen?

Mit einem Array von Funktionszeigern
http://www.mikrocontroller.net/articles/FAQ#Funktionszeiger
Gast #1901685
Lesenswert?

Der code ist NICHT getestet. Aber so in der Art könnte man's machen:

typedef void(*tpVoidFkt)(void);
#define byte unsigned char
#define NOFKT ((tpVoidFkt)0)

tpVoidFkt FktList[10];


void Init(void)
{
  byte bCtr = sizeof(FktList);
  while(bCtr--) FktList[bCtr] = NOFKT;
}

void SetFkt(byte bFktNbr, tpVoidFkt pFkt)
{
  FktList[bFktNbr] = pFkt;
}

void CallFkt(byte bFktNbr)
{
  if ( NOFKT != FktList[bFktNbr] ) (FktList[bFktNbr])();
}


void Test0(void)
{

}

void Test1(void)
{

}



void main(void)
{
      Init();

      SetFkt(0,&Test0);
      SetFkt(1,&Test1);

      CallFkt(0);
      CallFkt(1);
}
Moderator #1901886
Lesenswert?

Für Freunde kompakter Schreibweisen bietet C99 die Möglichkeit, das
Funktionspointerarray direkt mit in den Aufruf zu packen. Wem die
Schreibweise zu kryptisch ist (Alternative 1), kann den Aufruf auch
durch Makros etwas verschönern (Alternativen 2 und 3):
1
#include <stdio.h>
2

3
int add(int a, int b) { return a + b; }
4
int sub(int a, int b) { return a - b; }
5
int mul(int a, int b) { return a * b; }
6
int div(int a, int b) { return a / b; }
7

8
#define VCALL(i,r,a,...) ((r(*[])a){__VA_ARGS__}[(i)])
9
#define VCALLI(i,...) VCALL(i,int,(int,int),__VA_ARGS__)
10

11
int main(void) {
12
  int a=12, b=4, c, i;
13

14
  for(i=0; i<4; i++) {
15

16
    // Alternative 1: ohne Makro
17
    c = (int (*[])(int, int)){add, sub, mul, div}[i](a, b);
18

19
    // Alternative 2: mit universellem Makro
20
    //        + Selektorvariable
21
    //        |   + Datentyp des Rückabewerts
22
    //        |   |        + Datentypen der Argumente
23
    //        |   |        |              + Funktionen
24
    //        |   |        |              |            + Argumente
25
    //        |  _|_  _____|____  ________|_________  _|__
26
    c = VCALL(i, int, (int, int), add, sub, mul, div)(a, b);
27

28
    // Alternative 3: mit spezialisiertem Makro
29
    c = VCALLI(i, add, sub, mul, div)(a, b);
30

31
    printf("%d\n", c);
32
  }
33
  return 0;
34
}

Es ist natürlich Geschmackssache, ob man das wirklich so machen will.
Ich wollte es nur mal als Proof-of-Concept in den Raum stellen ;-)
Gast #1901950
Lesenswert?

O.T.
Für mich brauchte die Welt nur aus Pascal-Programmierern zu bestehen.
Das liegt schahr-weinlich daran, daß ich Algol als erste Sprache gelernt
habe. Ich weiß nicht, was sich die "C"-Erfinder dabei gedacht haben,
alle verfügbaren Sonderzeichen im Quelltext zu verhackstücken...
:-(
MfG Paul
#1901973
Lesenswert?

@  Paul Baumann (Gast)

>habe. Ich weiß nicht, was sich die "C"-Erfinder dabei gedacht haben,
>alle verfügbaren Sonderzeichen im Quelltext zu verhackstücken...
>:-(

Naja, C ist halt ein Kind der 70er, da war man mit dem LSD noch im 
breiten Versuchsstadium . . . ;-)
Gast #1902005
Lesenswert?

LSD? War das nicht das Zeug, nach dessen Einnahme man Deckenlampen ohne
Leiter wechseln konnte?
;-)

Herr Meier gab Kollegin Schmidt
Lysergsäure-diethyl-amid
Frau Schmidt schwebt rosa durch den Raum,
Herr Meier, -ja der fasst es kaum...

MfG Paul
Gast #1902013
Lesenswert?

@Klaus
Klasse! Heb das gut auf,-in ein paar Jahren werden sich die Leute wieder
damit befassen, wenn sie die Orientierung im Wirrwarr der heutigen
Programmiersprachen vollends verloren haben.
(Das meine ich ausnahmsweise mal ernst)
MfG Paul

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren