Mittels Switch Case zwischen Unterprogrammen in der main wechseln

OP #5189353
Lesenswert?

Hallo Leute,

wie kann man mittels switch case Unterprogramme auswählen? Ich möchte in 
der main Funktion zwischen den Unterprogrammen, manuell();, sar(); und 
tracking(); eine Wahl treffen, die im Sorcecode festgelegt werden kann.
Bin Anfänger und hoffe man kann mir paar Tipps geben.
1
int main(void) {
2
    while(1) {
3
        switch() {
4
            case 1: manuell();   break;
5
            case 2: sar();       break;
6
            case 3: tracking();  break;
7
        }
8
    }
9
}
#5189363
Lesenswert?

Hi

Da 'Unterprogramm' hier eher 'Funktion' sein wird: ja
Sehe kein Problem in Deinem Code.
Wenn doch, wird der Compiler Dir schon sagen, was Ihn stört - musst den 
ersten Compiler-Versuch ja nicht erst bei 4000 Zeilen Quelltext starten.

MfG

PS: Oh, da war gar Nichts in der switch-Anweisung drin :/ - Das hätte 
der Compiler aber wohl auch angemeckert.
#5189545
Lesenswert?

Du kannst das ganze auch gleich zu einem Zustandsautomat (State machine) 
entwickeln, so dass man zwischen den Unterprogrammen/Zuständen wechseln 
kann.

typedef enum
{
    MANUAL = 0,
    SAR,
    TRACKING
} state_t;

state_t state = MANUAL;

int main(void)
{
    while(1)
    {
        switch(state)
        {
            case MANUAL:
                manual();
                if(.....)
                    state = SAR;
                break;
                case SAR: sar();       break;
                case TRACKING: tracking();  break;
            default:
                puts("Fehler");
                state = MANUAL;
        }
    }
}
Gast #5189573
Lesenswert?

Y. L. schrieb:
> Bin Anfänger und hoffe man kann mir paar Tipps geben.

Benutze Google mit "C switch" als Suchargument. Es gibt genug C-Code im 
Netz.
Und - nein - es ist nicht verboten, irgendetwas in die case-Block zu 
schreiben. Auch Funktionsaufrufe sind erlaubt. Unterprogramme gibt es C 
nicht. Du kannst aber Funktionen mit Rückgabe eines Void verwenden.
#5189673
Lesenswert?

Moin,

Das schoene an C ist, dass man da auch prima solche kurzen Konstrukte 
schreiben kann - ganz ohne switch case:
1
int wahl;
2
void (*machwasichwill[])(void)={manuell,sar,tracking};
3

4
/* ... */
5

6
wahl=1;
7
machwasichwill[wahl]();


Obacht: wahl darf hier nur 0,1 oder 2 sein - sonst droht ewige 
Verdammnis.


Gruss
WK
Gast #5194463
Lesenswert?

Dergute W. schrieb:
> int wahl;
> void (*machwasichwill[])(void)={manuell,sar,tracking};
>
> /* ... */
>
> wahl=1;
> machwasichwill[wahl]();
1
machwasichwill[wahl < sizeof(machwasichwill) / sizeof(machwasichwill[0]) ?  wahl : 0]();

Dergute W. schrieb:
> Obacht: wahl darf hier nur 0,1 oder 2 sein - sonst droht ewige
> Verdammnis.

Nicht das wir den Ablaßhandel wieder einführen müssen.

;)
#5194485
Lesenswert?

Jetzt frag ich mich gerade, warum der Beitrag von  Dergute Weka und 
einigen anderen negativ bewertet wurde.

Denn was hier beschrieben wird, ist die Dispatcher Liste in 
ereignisgesteuerten Systemen ohne Preemption. Sowas wird gerne 
verwendet, wenn die System klein und leichtgewichtig sein sollen. Z.B. 
wenn es wenig Platz für einen Stack gibt.

Die Liste "machwasichwill" ist hier statisch, aber sowas kann man 
natürlich auch dynamisch gestalten, mit Prioritäten versehen usw. Damit 
kann man dann ganz unterschiedliche Scheduler konstruieren und ein sehr 
mächtiges Laufzeitsystem bauen.
Gast #5194610
Lesenswert?

Dergute W. schrieb:
> Das schoene an C ist, dass man da auch prima solche kurzen Konstrukte
> schreiben kann - ganz ohne switch case:

Zugegeben, dies kannte ich nicht.
Ich glaube auch nicht, dass diese Lektion ideal für Anfänger (der TO hat 
sich so bezeichnet) ist. Mir jedenfalls gefällt sein (korrigierter) 
Vorschlag besser, weil für mich übersichtlicher.
Kann diese Methode auch Funktionen mit unterschiedlicher Parameterlisten 
handeln oder nur leere bzw. gleiche?
Gast #5194621
Lesenswert?

Rolf H. schrieb:
> Jetzt frag ich mich gerade, warum der Beitrag von  Dergute Weka und
> einigen anderen negativ bewertet wurde.

(nicht von mir, aber) weil der TO als Anfänger nach der korrekten 
Schreibweise von switch fragte.
> Damit kann man dann ganz unterschiedliche Scheduler konstruieren
> und ein sehr mächtiges Laufzeitsystem bauen.
Ja. Aber erst nachdem Pointer und Funktionspointer und Lint dran waren.
#5194641
Lesenswert?

Moin,

HildeK schrieb:
>
> Zugegeben, dies kannte ich nicht.
> Ich glaube auch nicht, dass diese Lektion ideal für Anfänger (der TO hat
> sich so bezeichnet) ist. Mir jedenfalls gefällt sein (korrigierter)
> Vorschlag besser, weil für mich übersichtlicher.
Ja, ist mir klar, dass das fuer "Anfaenger" erstmal schwere Kost ist. 
Aber:
a.) Das lesen ja nicht nur Anfaenger und b.) Ich schrub ja auch, dass 
ich es schoen finde, dass man bei C auch solche Konstrukte schreiben 
kann. Und ich schreibte nicht, dass die Methode mit den 
Funktionspointern die einzig und alleine Seligmachende ist.

> Kann diese Methode auch Funktionen mit unterschiedlicher Parameterlisten
> handeln oder nur leere bzw. gleiche?
Die Methode wuerde ich nur anwenden, wenn alle Funktionen gleiche Typen 
bei den Argumenten und Rueckgabewerten haben. Sonst waere mein 
aesthetisches Empfinden sehr beeintraechtigt und es wird eine ueble 
Casterei um den Compiler zu beruhigen und ich wuerd' mal nicht voellig 
ausschliessen, dass da auch mal Bloedsinn passieren kann.

Gruss
WK
#5194664
Lesenswert?

Teo D. schrieb:
> Unleserlich, Fehler trächtig, schlecht(er) zu Debuggen, unnötig das
> einem Anfänger zu zeigen (ich fand's interessant, WTF).

Zum Teil berechtigt.

Unleserlich. Nun, das hat C so an sich. Man nennt es manchmal auch Krieg 
der Sterne.

Fehlerträchtig. Nein, es ist ein Array von Funktionen. Da kann man 
nichts falsch machen, wenn man es einfach so abschreibt.

Schlechter zu Debuggen. Nein, denn es ist der Semantik nach ein 
switch-Statement. Nur dass im switch-Statement die Sprungadressen 
verdeckt codiert werden und hier sichtbar sind.

Unnötig, das einem Anfänger zu zeigen. Richtig, aber hier lesen auch 
Fortgeschrittene mit. Den hilft es auf jeden Fall. Und der Anfänger kann 
bei Bedarf mal drauf zurück greifen.

Ich denke positives und negatives halten sich die Waaage.
#5194682
Lesenswert?

Rolf H. schrieb:
> Fehlerträchtig. Nein, es ist ein Array von Funktionen. Da kann man
> nichts falsch machen, wenn man es einfach so abschreibt.

Na ich stell mir da immer gleich ein größeres Konstrukt vor und da 
scheint es schnell, chaotisch/unübersichtlich zu werden.
...
...
...
Ach Quatsch. Wenn sich Auge und Hinterkopf erst dran gewöhnt hat....

Rolf H. schrieb:
> Unnötig, das einem Anfänger zu zeigen. Richtig, aber hier lesen auch
> Fortgeschrittene mit.

Meine Worte!
War halt nach eventuellen Gründen gefragt und naja, die gingen mir 
aus. ;)
#5194692
Lesenswert?

Moin,

Also sooo exotisch sind Arrays von Funktionspointern, bzw. structs, die 
als Member Funktionspointer enthalten auch wieder nicht. Linux ist voll 
davon. Une wenn ich in andere Kernel gucken koennte, bin ich mir sicher, 
dass es das dort genauso gibt.
Klar, um ein HelloWorld zu programmieren, brauch ich das nicht. Und wenn 
ich in Java oder C++ in irgendwelchen wilden Vererbungen schwelg', macht 
der Compiler halt die Drecksarbeit ohne dass ich den leisesten Schimmer 
hab, wie das dann wirklich funktioniert.

Gruss
WK
Gast #5195521
Lesenswert?

Zum Zeigen, OK, aber sonst ist oben m.E. case vorzuziehen, da die 
Funktionen "absolut" aber per Index gewählt werden.

Funktionspointer m.E. erst, wenn automatisch darüber itteriert wird, 
(z.B. innerhalb einer Menünavigation) oder ein Funktionspointer direkt 
gesetzt wird, also "fließend", etwa so:
1
void Func1(void);
2
void Func2(void);
3
void FuncDefault(void);
4

5
void Func1(void)
6
{
7
   ...
8
   ...
9
   if(...) Statemachine = Func2;
10
}
11

12
void Func2(void)
13
{
14
   ...
15
   ...
16
   if(...) Statemachine = Func1;
17
}
18
void FuncDefault(void)
19
{
20
   ...
21
   ...
22
   if(...) Statemachine = Func1;
23
}
24

25
void (*Statemachine)(void) = FuncDefault;
26

27
int main(void)
28
{
29
   for(;;)
30
   {
31
      Statemachine();
32
      if(...) 
33
      {
34
         Statemachine=FuncDefault;
35
      }
36
   }
37
}
Gast #5195875
Lesenswert?

Wenn die Umstellung nur beim Compilieren erfolgt und nicht zur Laufzeit 
wird der Compiler dir dieses Switch Case vermutlich eh rausschmeissen.

Daher würde ich sowas über einen define lösen, dann kann die Änderung 
auch schön über das Makefile erfolgen. Unterschiedliche Versionen per 
Quelltextänderung ist Pfusch.
#5196780
Lesenswert?

Hi

Dieter schrieb:
> Unterschiedliche Versionen per
> Quelltextänderung ist Pfusch.

Und ich dachte, wenn ich den Quelltext ändere, wäre eine neue 
Versions-Nummer fällig - dabei ist Das bisher nur Pfusch gewesen :/

Ein Glück, daß heute nicht noch erst über Alpha und Beta gegangen werden 
muß, wie Das wohl Früher so war.
Ein Hoch auf die neue Technik!

Wie sonst werden denn neuere Versionen 'entwickelt', wenn nicht durch 
Anpassung des Quelltext?
'Hmm - Heute compiliere ich Mal ohne Optimierung und schreibe ein Smilie 
in den Kommentar des Make-File'

Mit der Bitte um Aufklärung
Gast #5196784
Lesenswert?

> Wie sonst werden denn neuere Versionen 'entwickelt', wenn
> nicht durch Anpassung des Quelltext?

Indem man ein Icon woanders hin zieht und in einem Properties Tab einen 
Parameter ändert :-)

Zumindest hätten das einige Manager gerne so. Dementsprechend werden 
auch immer wieder neue Tools verkauft, die Programme ohne Programmieren 
erstellen können sollen.

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