Forum: Mikrocontroller und Digitale Elektronik Mittels Switch Case zwischen Unterprogrammen in der main wechseln


von Y. L. (ynynloxx)


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
}

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

1
int wahl = 2;
2
int main(void) {
3
    while(1) {
4
        switch(wahl) {
5
            case 1: manuell();   break;
6
            case 2: sar();       break;
7
            case 3: tracking();  break;
8
        }
9
    }
10
}

Suchtipp: "c enum switch"

von Patrick J. (ho-bit-hun-ter)


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.

: Bearbeitet durch User
von TU Student 1. (student0)


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;
        }
    }
}

: Bearbeitet durch User
von W.A. (Gast)


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.

von Dergute W. (derguteweka)


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

von stefan (Gast)


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.

;)

von Possetitjel (Gast)


Lesenswert?

Dergute W. schrieb:

> Das schoene an C ist, [...]

Dein Beispiel ist der schlagende Beweis, dass Schönheit im
Auge des Betrachters liegt.

von Rolf H. (b0d0)


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.

: Bearbeitet durch User
von Dergute W. (derguteweka)


Lesenswert?

Moin,

Possetitjel schrieb:
> Dergute W. schrieb:
>
>> Das schoene an C ist, [...]
>
> Dein Beispiel ist der schlagende Beweis, dass Schönheit im
> Auge des Betrachters liegt.

Hihi, jepp - so isses.

Gruss
WK

von HildeK (Gast)


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?

von A. S. (Gast)


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.

von Teo D. (teoderix)


Lesenswert?

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

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

Also, wenn ich da gewertet hätte.

von Dergute W. (derguteweka)


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

von Teo D. (teoderix)


Lesenswert?

Dergute W. schrieb:
> Die Methode wuerde ich nur anwenden, wenn

Jo, nur für Eventualitäten. Wie werden solche Funktionen bezeichnet, 
bzw. Suchbegriff(e)?

von Rolf H. (b0d0)


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.

von Teo D. (teoderix)


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. ;)

von Dergute W. (derguteweka)


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

von A. S. (Gast)


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
}

von Dieter (Gast)


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.

von Patrick J. (ho-bit-hun-ter)


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

von Stefan F. (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.