Forum: Mikrocontroller und Digitale Elektronik Frage zum Case Switch, bzw suche Konstrukt das nach bits schaltet


von J. T. (chaoskind)


Lesenswert?

MoinMoin,

im Rahmen meines GameOfLife Gebastels stellt sich mir eine Frage.

Ich habe eine Variable, die ich als Satz von Flags benutze. In einem 
Case Switch wollte ich nun auswerten, ob ein oder mehrere Sachen 
passieren sollen.

Gedacht hatte ich mir das folgendermaßen:
1
#define Blah 0
2
#define Blub 1
3
4
uint8_t Flags = 0;
5
6
switch(Flags)
7
{
8
  case( (Flags & (1 << Blah)) ): dosomething(); break;
9
  case( (Flags & (1 << Blub)) ): dosomethingelse(); break;
10
  default: break;
11
}

ich möchte also, dass jedes Bit der Flags für einen Case steht.

So geht das aber nich, meckert der Compiler. Also hab ich das erstmal so 
gelöst:

1
#define Blah 1
2
#define Blub 2
3
4
uint8_t Flags = 0;
5
6
switch(Flags)
7
{
8
  case( Blah ): dosomething(); break;
9
  case( Blub ): dosomethingelse(); break;
10
  default: break;
11
}

So müsste ich dann aber auch noch einen Case für den Fall dass Blah und 
Blup gesetzt sind machen. Wenn ich dann nachher 8 Sachen zu setzen habe, 
müsste ich also 256 Cases schreiben. Dann kann ich ja genauso gut ein 
If-Monster bauen.

Gibt es da einen effektiven Weg, sowas bitweise auszuwerten?

MfG Chaos

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du kannst für /case/-Zweige nur Konstanten verwenden. Dazu gehören auch 
Ausdrücke, die zur Übersetzungszeit berechnet werden.

Dazu kommt, daß Dein erster Ansatz nicht eindeutig ist:

Wenn beide Bits gesetzt sind, müssten beide case-Zweige abgearbeitet 
werden. So aber arbeitet switch/case nicht.


Du wirst um Dein if-"Getüm" nicht herumkommen.

von J. T. (chaoskind)


Lesenswert?

Schade...
Danke dir trotzdem für deine, wenn auch unerfreuliche, Antwort.
Rufus Τ. F. schrieb:
> Wenn beide Bits gesetzt sind, müssten beide case-Zweige abgearbeitet
> werden. So aber arbeitet switch/case nicht.
und für diese Klarstellung.

Eigentlich auch logisch, des breaks; wegen...

Dann aber doch lieber 8ifs statt 256 cases :D

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

J. T. schrieb:
> Eigentlich auch logisch, des breaks; wegen...

 Nein, eigentlich ist es wegen Sprungtabelle oder Binärbaum, wenn
 ich mich richtig erinnere.
 Deswegen ist es auch schneller als if - alle Sprungadressen stehen
 schon bei Kompilieren fest.

von Teo D. (teoderix)


Lesenswert?

KA was du wirklich vorhast.
Tuts das?
1
 #define Blah 1
2
 #define Blub 2
3
 
4
 uint8_t Flags = 0;
5
 
6
 switch(Flags & deine Wunsch-Bitmaske)))
7
 {
8
   case 0: dosomething(); break;
9
   case 1: dosomethingelse(); break;
10
   case 2: ...
11
   case 4: ...
12
   case 8: ...
13
   default: break;
14
 }

Ohne Breaks kanns auch ganz lustig sein. Die Reihenfolge ist ja 
beliebig.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Teo D. schrieb:
> Tuts das?

 Nein, bestimmt nicht.

 Was ist wenn z.B. Flags == 3 (Blah und Blub gesetzt) ?

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


Lesenswert?

J. T. schrieb:
> Dann kann ich ja genauso gut ein If-Monster bauen.

Die 8 if's sind in deinem Fall ja noch kleiner als es 8 
Case-Anweisungen.wären. das

von Nop (Gast)


Lesenswert?

Marc V. schrieb:

> Deswegen ist es auch schneller als if

Wie der Compiler es umsetzt, ist nicht spezifiziert. Er kann das auch 
mit if/else machen. Sprungtabelle ist nur dann wahrscheinlich, wenn es 
sich um einen sehr begrenzten Wertebereich handelt, den man überhaupt 
mit einer Sprungtabelle sinnvoll hinkriegen kann.

Deswegen sollte man mit switch vorsichtig sein, wenn es um Performance 
geht, weil eine kleine Änderung überraschend große Folgen haben kann.

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Sprungtabelle ist nur dann wahrscheinlich, wenn es
> sich um einen sehr begrenzten Wertebereich handelt

Da mit der Tabelle ein gewisser Overhead verbunden ist, müssen genug 
Fälle zusammen kommen, damit es sich lohnt.

Wobei switch mitunter einen Abfrage-Baum implementiert, was ein 
Programmierer mit if kaum zustande bekommt.

: Bearbeitet durch User
von Axel S. (a-za-z0-9)


Lesenswert?

J. T. schrieb:
> So müsste ich dann aber auch noch einen Case für den Fall dass Blah und
> Blup gesetzt sind machen. Wenn ich dann nachher 8 Sachen zu setzen habe,
> müsste ich also 256 Cases schreiben.

Du bist da gedanklich schon auf den richtigen Weg. Es sind nur noch ein 
paar Schritte zu gehen.

> Dann kann ich ja genauso gut ein If-Monster bauen.

Nur daß das - zumindest im Vergleich zu einem switch() mit 256 cases - 
eben gerade kein Monster wird.

Switch|case vergleicht eine Variable mit einer Liste von Konstanten, 
es kann nur maximal einer der cases genommen werden. Es kann zwar 
trotzdem mehr als einer der Codeblöcke ausgeführt werden, entweder weil 
man ein break vergessen hat oder weil man dieses fall through 
tatsächlich wollte - aber das ist eine andere Geschichte.

Der Punkt ist: Bits in einem Byte sind unabhängig voneinander. Deswegen 
ergibt es auch keinen Sinn, mit switch|case einzelne Bits testen zu 
wollen. Der normale, sinnvolle Weg sind 8 unabhängige if|then|else 
Konstrukte.

Inwiefern das dann zu deiner Programmlogik paßt, ist wieder eine andere 
Sache. Speziell für Game Of Life brauchst du die Anzahl der gesetzten 
Bits. Und die kann zwischen 0 und 8 liegen. Und da sind wirklich nur 9 
einzelne Fälle zu betrachten. Es kommt nicht darauf an, auf welche 
Bits jeweils gesetzt sind. Insofern ist switch|case schon das richtige 
Konstrukt, nur darfst du dem nicht die Bitmaske direkt verfüttern, 
sondern mußt vorher die Anzahl der gesetzten Bits zählen.

Das ist eine durchaus häufig gebrauchte Operation, aber leider hat C 
keinen Operator dafür. Manche CPU haben aber Assembler-Instruktionen 
dafür und dann stellt der C-Compiler meist eine "builtin" Funktione zum 
Zugriff auf diese Operation bereit. Von C-Seite sieht das dann wie ein 
FUnktionsaufruf aus, der Compiler macht daraus aber u.U. nur eine 
einzige Instruktion.

Aber auch ohne das, haben sich seit vielen Jahren schon Programmierer 
darüber Gedanken gemacht, wie man diese Operation effizient hinkriegt. 
Das Internet kann helfen. Guckst du z.B. hier:

https://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer

von J. T. (chaoskind)


Lesenswert?

Achim S. schrieb:
> Die 8 if's sind in deinem Fall ja noch kleiner als es 8
> Case-Anweisungen.wären. das

Aber es wären doch 256 cases wenn man 8 bit auszuwerten hat? Wo nimmst 
du die 8 Case-Anweisungen her?

Axel S. schrieb:
> Du bist da gedanklich schon auf den richtigen Weg. Es sind nur noch ein
> paar Schritte zu gehen.  .....

Danke dir für die Ausführungen. Den Link muss ich mir nochmal genauer zu 
Gemüte führen, beim ersten Überfliegen machte es noch nicht klick :D

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

J. T. schrieb:
> Aber es wären doch 256 cases wenn man 8 bit auszuwerten hat? Wo nimmst
> du die 8 Case-Anweisungen her?

256 Fälle sind es, wenn man die Bits zusammengesetzt betrachtet. 8, wenn 
jedes Bit einzeln und unabhängig von den anderen betrachtet wird.

Je nachdem, was mit den 8 Bits codiert wird, ist die eine oder die 
andere Sichtweise anzuwenden.

Ohne weitere Informationen des Threadstarters darüber, was seine Bits 
(und gegebenenfalls deren Kombinationen) bedeuten, lässt sich die 
Problemstellung nicht abschließend lösen.

von A. S. (Gast)


Lesenswert?

J. T. schrieb:
> Aber es wären doch 256 cases wenn man 8 bit auszuwerten hat? Wo nimmst
> du die 8 Case-Anweisungen her?

Es bezog sich auf Dein

J. T. schrieb:
> If-Monster

Die gibt es aber sowieso nicht. Was es gibt sind if / else if -Monster. 
Die entsprechend einem Case und haben die "Switch" Anweisung in jeder 
Abfrage wiederholt.

Mir ging es also darum: Wenn Du das mit if hingeschrieben hättest, wäre 
der Code schöner als das, was Du Dir mit case erhofft hast.

von Axel S. (a-za-z0-9)


Lesenswert?

Achim S. schrieb:
> J. T. schrieb:
>> Aber es wären doch 256 cases wenn man 8 bit auszuwerten hat? Wo nimmst
>> du die 8 Case-Anweisungen her?
>
> Es bezog sich auf Dein
>
> J. T. schrieb:
>> If-Monster
>
> Die gibt es aber sowieso nicht. Was es gibt sind if / else if -Monster.

Wenn man 8 unabhängige Bits testet, dann auch nicht. Es sind dann 8 
unabhängige if()s. Nicht geschachtelt oder so.

Aber gut, wenn die Bits den Zustand der Nachbarn in einem Game Of Life 
Gitter repräsentieren, dann will man die Bits ja gar nicht unabhängig 
betrachten. Was man für die Berechnung des Folgezustands braucht, ist 
die Anzahl der lebenden Nachbarn; vulgo die Anzahl der gesetzen Bits.

von Stromverdichter (Gast)


Lesenswert?

Wenn es nur um die Lesbarkeit geht und du gerne unbedingt Einzeiler 
draus machen möchtest, könntest du auch mit Funktionspointern arbeiten. 
Ich mache das nicht so oft, daher bitte Beispielcode nicht auf die 
Waagschale werfen.

Hier sind die Bits 1 und 3 gesetzt in Flags, die Auswertung startet die 
Funktionen print1() und print3(). Es wäre auch möglich, per returnValue 
der Funktion "do_ifBitIsSet" eine Funktion auszuführen, ich habe den 
eigentlichen Aufruf aber lieber in der Funktion.
Die Bits würde ich per ENUM definieren, mit Namen arbeitet es sich 
einfach leichter.

1
#include <stdio.h>
2
#include <stdint.h>>
3
4
5
typedef void (*functionToPointAt)(void);
6
7
void do_ifBitIsSet(uint16_t flags, uint16_t bitToTest, functionToPointAt function)
8
{
9
  if (flags&(bitToTest<<1))
10
    function();
11
}
12
13
void print1(void){
14
  printf("Funktion 1 wurde aufgerufen\n");
15
}
16
17
void print2(void){
18
  printf("Funktion 2 wurde aufgerufen\n");
19
}
20
21
void print3(void){
22
  printf("Funktion 3 wurde aufgerufen\n");
23
}
24
25
int main()
26
{
27
  uint16_t flags =  0x3;
28
 do_ifBitIsSet(flags, 1, print1);
29
 do_ifBitIsSet(flags, 2, print2);
30
 do_ifBitIsSet(flags, 3, print3);
31
}

von Joachim B. (jar)


Lesenswert?

Axel S. schrieb:
> Switch|case vergleicht eine Variable mit einer Liste von Konstanten,
> es kann nur maximal einer der cases genommen werden.

ist zwar eine doofe Idee, nie probiert, aber in C denke ich kann ich im 
Case die Variable ändern dann mit goto zum switch zurückspringen.

von STK500-Besitzer (Gast)


Lesenswert?

Bei eine uint8_t Variable braucht man 8 Abfragen und eine Schleife:
1
for(uint8_t i = 1; i !=0; i<<1){
2
switch(Flags & i){
3
case 1:
4
tuwas();
5
break;
6
case 2:
7
tuwas();
8
break;
9
case 4:
10
tuwas();
11
break;
12
case 8:
13
tuwas();
14
break;
15
case 16:
16
tuwas();
17
break;
18
case 32:
19
tuwas();
20
break;
21
case 64:
22
tuwas();
23
break;
24
case 128:
25
tuwas();
26
break;
27
default:
28
tuwas();
29
break;
30
31
}

anders geht das doch gar nicht mit switch case.

von J. T. (chaoskind)


Lesenswert?

Achim S. schrieb:
> J. T. schrieb:
>> Aber es wären doch 256 cases wenn man 8 bit auszuwerten hat? Wo nimmst
>> du die 8 Case-Anweisungen her?
>
> Es bezog sich auf Dein
>
> J. T. schrieb:
>> If-Monster
>
> Die gibt es aber sowieso nicht. Was es gibt sind if / else if -Monster.
> Die entsprechend einem Case und haben die "Switch" Anweisung in jeder
> Abfrage wiederholt.
>
> Mir ging es also darum: Wenn Du das mit if hingeschrieben hättest, wäre
> der Code schöner als das, was Du Dir mit case erhofft hast.

Alles klar! Danke dir für die Ausführung.

Rufus Τ. F. schrieb:
> 256 Fälle sind es, wenn man die Bits zusammengesetzt betrachtet. 8, wenn
> jedes Bit einzeln und unabhängig von den anderen betrachtet wird.
>
> Je nachdem, was mit den 8 Bits codiert wird, ist die eine oder die
> andere Sichtweise anzuwenden.
>
> Ohne weitere Informationen des Threadstarters darüber, was seine Bits
> (und gegebenenfalls deren Kombinationen) bedeuten, lässt sich die
> Problemstellung nicht abschließend lösen.

Das hab ich ja angedeutet mit dem "wenn dann aber Blah und Blub sind, 
bräuchte ich noch nen 3ten case". Das ganze soll schon irgendwie 
zusammenhängend betrachtet werden, auch wenn es nicht wirklich 
zusammengehört. Ich wollte einfach die Möglichkeit haben, beim Debuggen 
unterschiedliche "Figuren" einzusetzen, indem ich die entsprechende Flag 
setze. Wenn ich FigurA reinhaben will, setz ich die Flag auf 0b00000001,
will ich FigurB, dann wird die Flag auf 0b00000010 gesetzt usw. Will ich 
nun mehrere gleichzeitig reinschmeißen, also Flag = 0b00000011.

Meine Hoffnung war, es gäbe etwas dass wie ein Switch funktioniert, aber 
mit Variablen umkann. Gibt es aber nicht, wie ja nun geklärt wurde. Was 
mir nun in Zusammenhang mit der Funktion des Case Switch auch irgendwie 
einleuchtet. Bei Variablen könnten ja "nicht-vordefinierte-"Cases"" 
rauskommen.

Axel S. schrieb:
> Aber gut, wenn die Bits den Zustand der Nachbarn in einem Game Of Life
> Gitter repräsentieren, dann will man die Bits ja gar nicht unabhängig
> betrachten. Was man für die Berechnung des Folgezustands braucht, ist
> die Anzahl der lebenden Nachbarn; vulgo die Anzahl der gesetzen Bits.

Hat in diesem Fall aber, wie oben angemerkt, nichts mit den Nachbarn zu 
tun. Auch wenn es in einem GoL ein naheliegender Gedanke ist.

Stromverdichter schrieb:
> #include <stdio.h>
> #include <stdint.h>>
>
> typedef void (*functionToPointAt)(void);
>
> void do_ifBitIsSet(uint16_t flags, uint16_t bitToTest, functionToPointAt
> function)
> {
>   if (flags&(bitToTest<<1))
>     function();
> }
>
> void print1(void){
>   printf("Funktion 1 wurde aufgerufen\n");
> }
>
> void print2(void){
>   printf("Funktion 2 wurde aufgerufen\n");
> }
>
> void print3(void){
>   printf("Funktion 3 wurde aufgerufen\n");
> }
>
> int main()
> {
>   uint16_t flags =  0x3;
>  do_ifBitIsSet(flags, 1, print1);
>  do_ifBitIsSet(flags, 2, print2);
>  do_ifBitIsSet(flags, 3, print3);
> }

Vom sich lesen lassen ist das genau das, was mir vorschwebte. Aber nach 
ein wenig überlegen prüft dass ja auch alles einzeln durch. Aber daran 
führ wohl kein Weg vorbei. Dennoch gefällt mir deine Formulierung 
ziemlich gut und ich werd versuchen, sie mir zu merken und zu benutzen! 
Danke dir dafür.

Stromverdichter schrieb:
> Wenn es nur um die Lesbarkeit geht und du gerne unbedingt Einzeiler
> draus machen möchtest, könntest du auch mit Funktionspointern arbeiten.

Eigentlich ging es mir darum, um die If-Abfragen drumherumzukommen. Aber 
umso mehr ich überlege, ist das rein logisch gar nicht möglich. 
Nebenbei, wie bekomme ich denn einen Pointer auf eine Funktion? Ich werd 
nebenbei auch mal Google fragen, aber falls du Lust und eine gute 
Erklärung hast, nur her damit. Persönlich formuliertes find ich meist 
angenehmer als den Krams aus irgendwelchen Tutorials ;-)

Joachim B. schrieb:
> ist zwar eine doofe Idee, nie probiert, aber in C denke ich kann ich im
> Case die Variable ändern dann mit goto zum switch zurückspringen.

Klingt eigentlich erstmal ganz plausibel. Wobei ich noch nie mit goto 
gearbeitet habe, weil eigentlich überall wo man hier mal ein "goto" 
gelesen hat, gleich das panische Gekreische losging "goto ist BÖÖÖSE" 
"lass das mit dem goto" usw :D

STK500-Besitzer schrieb:
> Bei eine uint8_t Variable braucht man 8 Abfragen und eine
> Schleife:for(uint8_t i = 1; i !=0; i<<1){
> switch(Flags & i){

Ist das nicht dass was ich im Eröffnungspost hatte? Da steht doch die 
Switchvariable auch nicht fest zur Laufzeit? Bzw damit machst du doch 
Unterschiedliche Switches draus?

nehmen wir an:
Flags = 0b00000001  d.h im ersten Durchlauf steht da
switch( 0b00000001 & 0b00000001)... was steht da überhaupt???

steht da switch(die adresse von der variablen)?
oder steht da switch(der wert der variablen)?

Irgendwie verwirre ich mich grad selbst immer mehr...

: Bearbeitet durch User
von boah ... (Gast)


Lesenswert?

J. T. schrieb:
> flags&(bitToTest<<1)

noch mal drüber nachdenken ...

von J. T. (chaoskind)


Lesenswert?

boah ... schrieb:
>> flags&(bitToTest<<1)

Der Teil ist soweit klar, wobei ich flags&(1<<bitToTest) schreiben würd 
oder nicht? Damit maskiere ich das gewünschte Bit aus der Flag aus. Aber 
das steht zur Laufzeit ja nicht fest. Je nachdem ob das Bit gesetzt ist 
oder nicht, ist es gesetzt oder nicht ;-).

Ich versuche nochmal aufzudröseln was mich verwirrt.

Also die einzelnen Cases müssen konstant sein. Wenn ich nun switch(blah) 
schreibe, wird nachgeschaut welchen Wert die Variable blah zur Zeit hat. 
Auf die Casenummer dieses Wertes wird dann gesprungen. Wobei ein 
Casenummer wie gesagt zur Laufzeit feststehen muss.

Im Switch selbst darf/muss aber eine Variable stehen. Dass heißt doch 
aber dass switch(blah) und switch(blah & i) überhaupt nicht die selben 
Switches sind?

Ich hoffe irgendwer versteht, was ich nicht verstehe :D

von boah ... (Gast)


Lesenswert?

J. T. schrieb:
> Ich versuche nochmal aufzudröseln was mich verwirrt.

es steht doch hier schon:
Beitrag "Re: Frage zum Case Switch, bzw suche Konstrukt das nach bits schaltet"

und ob
for(uint8_t i = 1; i !=0; i<<1){
switch(Flags & i){

oder
for(uint8_t i = 0; i < 8; i++{
switch(Flags & (1 << i)){

ist doch egal.

von Egon D. (Gast)


Lesenswert?

J. T. schrieb:

> Also die einzelnen Cases müssen konstant sein. Wenn
> ich nun switch(blah) schreibe, wird nachgeschaut
> welchen Wert die Variable blah zur Zeit hat.
> Auf die Casenummer dieses Wertes wird dann gesprungen.
> Wobei ein Casenummer wie gesagt zur Laufzeit feststehen
> muss.
>
> Im Switch selbst darf/muss aber eine Variable stehen.
> Dass heißt doch aber dass switch(blah) und
> switch(blah & i) überhaupt nicht die selben Switches
> sind?

Auffassungssache.

Bei "switch(blah)" repräsentiert "blah" direkt die
Fallnummer.

Bei "switch(blah & i)" wird die Fallnummer erstmal aus
einer vorgeschalteten Abbildung bestimmt, nämlich aus
blah & i. Es gibt keine Variable, die direkt die Fallnummer
repräsentiert; daher finde ich diese Schreibweise auch
unschön. Es passiert zuviel auf einmal.

Ich würde also eher sagen: Der Switch ist derselbe, nur
sind die Fallnummern anders definiert.

von Georg Gast 1 (Gast)


Lesenswert?

boah ... schrieb:
> J. T. schrieb:
>> Ich versuche nochmal aufzudröseln was mich verwirrt.
>
> es steht doch hier schon:
> Beitrag "Re: Frage zum Case Switch, bzw suche Konstrukt das nach bits schaltet"
>
> und ob
> for(uint8_t i = 1; i !=0; i<<1){
> switch(Flags & i){
>
> oder
> for(uint8_t i = 0; i < 8; i++{
> switch(Flags & (1 << i)){
>
> ist doch egal.

Nein, ist es nicht.

Die 2. Variante funktioniert (bis auf die vergessene Klammer),
die 1. nicht, das ist eine Endlosschleife.

Die Compiler-Warnung "statement with no effect [-Wunused-value]" hat 
eine Bedeutung. Oder gibt es hier immer noch Superhelden, die ohne 
eingeschaltete Warnungen compilieren?

Georg



Auflösung: es muss schon "i <<= 1" heißen.

von J. T. (chaoskind)


Lesenswert?

Ich glaub es hat grad klick gemacht. Mein Fehler war ja das case(blah&i) 
versuchen wollte. Quasi ein Variabler case. Und das geht nicht. Ok der 
Knoten hat sich aufgelöst.

Ich hatte gedanklich irgendwie die Variable direkt dem Switch 
zugeordnet. Quasi "das ist DER blah-Switch".

Aber es gibt wohl einfach nur das Konstrukt switch. Dem übergibt man 
dann einen Wert per Variablen. Und dann wird einfach zu dem 
Wert/Fallnummer gesprungen.
Wäre aus irgendeinem blöden Grund blah immer auf dem selben Wert, sagen 
wir mal 42, könnte man dann auch einfach
1
switch(42)
2
case1:break;
3
.
4
.
5
case42:blah();break;
6
default:break;
schreiben? Klar macht das aus des Programmierers Sicht keinen Sinn, aber 
wäre das in diesem Fall das gleiche wie switch(blah)?

von Egon D. (Gast)


Lesenswert?

J. T. schrieb:

> Das hab ich ja angedeutet mit dem "wenn dann
> aber Blah und Blub sind, bräuchte ich noch
> nen 3ten case". Das ganze soll schon irgendwie
> zusammenhängend betrachtet werden, auch wenn
> es nicht wirklich zusammengehört.
> [...]
> Eigentlich ging es mir darum, um die If-Abfragen
> drumherumzukommen. Aber umso mehr ich überlege,
> ist das rein logisch gar nicht möglich.

Ich habe Dein Problem nicht genau verstanden.

Suchst Du so eine Art Entscheidungstabellentechnik?
Also:
- mehrere zu prüfende Bedingungen,
- je Bedingung i.d.R. mehrere mögliche Belegungen,
- "schwache Besetzung" der Tabelle, d.h. es ergeben
  sich rechnerisch sehr viel mehr Kombinationen, als
  tatsächlich real zu behandeln sind.

Wenn ja: Das kann man behandeln, indem man in der ersten
Verfahrensstufe die Bedingungen auf eine Fallnummer
abbildet (einfach mit if/then/else) und in der zweiten
Verfahrensstufe die Fallnummer in ein switch/case
hineinsteckt, das dann zur richtigen Behandlungsroutine
verzweigt.

von Egon D. (Gast)


Lesenswert?

J. T. schrieb:

> Ich glaub es hat grad klick gemacht. Mein Fehler war
> ja das case(blah&i) versuchen wollte. Quasi ein
> Variabler case. Und das geht nicht.

Warum soll das nicht gehen?

Der Compiler sollte damit kein Problem haben -- aber
für normal talentierte Programmierer ist das nicht
lesbar.

Welcher Fall wird angesprungen, wenn
blah = 0x55 und
i    = 0xAA gilt?
Völlig offensichtlich: Fall 0 :)


> Ich hatte gedanklich irgendwie die Variable direkt
> dem Switch zugeordnet. Quasi "das ist DER blah-Switch".

Naja, in der Regel wird man das genau so machen: Es gibt
eine Variable, deren Belegungen den einzelnen Fällen
zugeordnet werden sollen.

Das ist aber eine Beschränkung, die durch den Menschen
diktiert wird -- ich sehe keinen technischen Grund, warum
der Computer nicht statt der Variablen einen Ausdruck
akzeptieren sollte. Nur ist halt switch (a ^ b) extrem
beschissen zu debuggen.


> Aber es gibt wohl einfach nur das Konstrukt switch. Dem
> übergibt man dann einen Wert per Variablen. Und dann wird
> einfach zu dem Wert/Fallnummer gesprungen.

Richtig.
Jede mögliche Belegung der Variablen (jedes "Bitmuster")
repräsentiert einen möglichen Zweig.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Um die Konfusion auf ein neues Level zu bringen - wie waers mit einem 
Array aus Funktionspointern, um die switch-case anweisung zu "umgehen"?
1
#include <stdio.h>
2
3
static int bla(int nei) {
4
  int naus=1+nei;
5
  return naus;
6
}
7
8
static int blupp(int nei) {
9
  int naus=2+5*nei;
10
  return naus;
11
}
12
13
static int schnodder(int nei) {
14
  int naus=3-2*nei;
15
  return naus;
16
}
17
18
int main() {
19
  static int (*functable[])(int)={schnodder,bla,blupp,schnodder,schnodder};
20
  int naus,nei,whichfunction;
21
22
  nei=11;
23
  whichfunction=2;
24
25
  naus=functable[whichfunction](nei);
26
27
  printf("naus=%d\n",naus);
28
29
  return 0;
30
}

da muss dann halt das Funktionspointerarray so initialisiert werden, 
dass abhaengig vom Wert von whichfunction eben die "richtige" Funktion 
aufgerufen wird.

Gruss
WK

von Ratgeber (Gast)


Lesenswert?

Bla, Blupp, Schnodder...

:))

Du hast schöne Variablennamen! Da macht das Lesen von Quelltexten gleich 
viel mehr Freude.

von 80er (Gast)


Lesenswert?

Ratgeber schrieb:
> Bla, Blupp, Schnodder...
>
> :))
>
> Du hast schöne Variablennamen! Da macht das Lesen von Quelltexten gleich
> viel mehr Freude.

Gute Kinderstube; muß man pflegen.

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.