Anzahl der Cases rausfinden

Persönliche Seite #7506734
Lesenswert?

Naja, in GCC geht es mit einem Trick wenn man ein Makro für "case" verwendet:

1
#include <stdio.h>
2

3
#define CASE(X) { (void) __COUNTER__; } case X
4

5
int func (int i)
6
{
7
    switch (i)
8
    {
9
        CASE(1): return i + 1;
10
        CASE(3): return i - 2;
11
        default: break;
12
    }
13
    printf ("%d cases\n", __COUNTER__);
14
    return i;
15
}
16

17
int main (void)
18
{
19
    func (2);
20
    return 0;
21
}

Dann laufen lassen:

1
$ gcc case.c -o case.x -Wall && ./case.x
2
2 cases

Bei mehr als einem switch pro Translation Unit wird das dann etwas aufwendiger, weil m.E. kann mann COUNTER nicht zurücksetzen.

Und der Wert steht nur nach dem switch zur Verfügung.

Moderator (Firma: Titel) Persönliche Seite #7506885
Lesenswert?

Nuri O. schrieb:

Kann man irgenwie mit einer Funktion während dem Programmverlauf die Anzahl der Cases einer switch-case-Verzweigung herausfinden ?

Bei solchen Lösungsansätzen würde mich das zugrundeliegende Problem interessieren. Oder andersrum: was bringt es, wenn man weiß, wieviele if- oder case-Abfragen ein Programm an einer bestimmten Stelle hinter sich hat?

OP #7507036
Lesenswert?

Lothar M. schrieb:

Bei solchen Lösungsansätzen würde mich das zugrundeliegende Problem interessieren.

War tatsächlich nur aus neugier. Ich bin kein anfänger, aber auch kein Profi und ich versuche immer alles so zu programmieren, dass ich bei Änderungen so wenig andere Codeteile anpassen muss.

Ich erzeuge eine Random zahl und führe dann den entsprechenden Case aus. Dafür muss ich ja wissen wie viele ich habe. Hatte mich dann gefragt, ob man das statt händisch auch irgendwie auslesen kann. Villeicht lernt man ja was neues :)

Johann L. schrieb:

Und der Wert steht nur nach dem switch zur Verfügung.

Ah schade, aber die probier ich mal aus, danke

Mfg

(Firma: Gast) #7507038
Lesenswert?

Nuri O. schrieb:

Ich erzeuge eine Random zahl und führe dann den entsprechenden Case aus. Dafür muss ich ja wissen wie viele ich habe. Hatte mich dann gefragt, ob man das statt händisch auch irgendwie auslesen kann. Villeicht lernt man ja was neues :)

Dann ist switch/case sicherlich das falsche Sprachmittel. Denn eine durchnummerierte case "Aufzählung" ist ein Sonderfall, welcher genau so, oder gar noch effektiver, mit eine Sprungleiste, oder einem FunktionPointerArray abgehandelt werden kann. Und die Größe eines Arrays, oder einer Liste, lässt sich jederzeit herausfinden.

Hatte mich dann gefragt,

Vermutlich eine falsche Frage, weil dein C++, welches du verwendest, das nicht hergibt.

(Firma: Gast) #7507064
Lesenswert?

Nuri O. schrieb:

Wie würde das aussehen ?

1
using FuncPtr = void(*)();
2

3

4
void huchFunc()
5
{
6
  Serial.println("huch");
7
}
8

9
FuncPtr functions[]
10
{
11
  [](){Serial.println("tue dies");},
12
  [](){Serial.println("tue das");},
13
  huchFunc,
14
  [](){Serial.println("tue jenes");},
15
  [](){Serial.println("tue was anderes");},
16
};
17

18
template<size_t N> void randomFuc(FuncPtr (&func)[N])
19
{
20
  func[random(N)]();
21
}
22

23
void setup() 
24
{
25
  Serial.begin(9600);
26
}
27

28
void loop() 
29
{
30
  randomFuc(functions);
31
  delay(1000); // nur damit es nicht zu schnell durchhuscht
32
}

Falls dir davon irgendwas "spanisch" vorkommt, ein gutes modernes C++ Grundlagenbuch hilft da weiter.

#7507087
Lesenswert?

Nuri O. schrieb:

Ich erzeuge eine Random zahl und führe dann den entsprechenden Case aus.

Nein, der Compuer führt zu deiner Zahl passende case-Statements aus. Meist eins, aber mit Fall-Through gehen auch mehr für eine Zahl.

Dafür muss ich ja wissen wie viele ich habe.

Die Aussage ergibt keinen Sinn. "wie viele" von was? Und warum musst du das "wissen". Du arbeitest mit einem mentalen Modell was keinen Sinn ergibt, aber du willst uns auch nicht verraten was das wirklich soll.

Du hast die case-Statements geschrieben. Die sind fest in deinem Code. Die kannst du abzählen. 1, 2, 3, ... ganz viele.

Arduino F. schrieb:

Dann ist switch/case sicherlich das falsche Sprachmittel. Denn eine durchnummerierte case "Aufzählung" ist ein Sonderfall, welcher genau so, oder gar noch effektiver, mit eine Sprungleiste, oder einem FunktionPointerArray abgehandelt werden kann.

Nein. Jeder halbwegs brauchbare C-Compiler erkennt das und legt für sequenzielle case-Statements Sprungtabellen an. Wenn es sein muss abschnittsweise und mit zusätzlichen eingestreuten Tests für nicht-sequenzielle Werte.

Und die Größe eines Arrays, oder einer Liste, lässt sich jederzeit herausfinden.

Und warum will man das tun? Man schreibt z.B. sechs case-Statements, dann hast man sechs Statements. Das werden zur Laufzeit nicht mehr oder weniger. Das sind genau die, die du hin geschrieben hast.

(Firma: Gast) #7507100
Lesenswert?

Hannes J. schrieb:

Nein. Jeder halbwegs brauchbare C-Compiler erkennt das und legt für sequenzielle case-Statements Sprungtabellen an. Wenn es sein muss abschnittsweise und mit zusätzlichen eingestreuten Tests für nicht-sequenzielle Werte.

Case Kaskaden werden nicht garantiert zu Sprungtabellen. Stark abhängig von den Optimierungseinstellungen.

Sie degenerieren auch mal zu einer Vergleichs/Entscheidungskette, vergleichbar mit einer if/else Kaskade.

Und das kann total ekelig werden. Kleinste Änderungen im Code ändern dann massiv die Größe des generierten Codes und vor allen Dingen die Laufzeit.

#7507137
Lesenswert?

Hannes J. schrieb:

Und die Größe eines Arrays, oder einer Liste, lässt sich jederzeit herausfinden.

Und warum will man das tun?

Zur Erleichterung? Zur Vermeidung von Fehlern?

Man schreibt z.B. sechs case-Statements, dann hast man sechs Statements. Das werden zur Laufzeit nicht mehr oder weniger.

Nein, aber zur Programmierzeit können es mehr oder weniger werden. Und dann ist es geschickt, wenn man nicht jedes mal daran denken muss, noch irgendwo eine magic number anpassen zu müssen. Der Computer ist eigentlich ziemlich gut im Zählen, also warum soll man das dann für ihn erledigen?

#7507201
Lesenswert?

Rolf M. schrieb:

Nein, aber zur Programmierzeit können es mehr oder weniger werden. Und dann ist es geschickt, wenn man nicht jedes mal daran denken muss, noch irgendwo eine magic number anpassen zu müssen.

Wozu soll diese Magic-Number dienen? Das konnte keiner von euch Helden bisher beantworten.

Wer die Kontrolle über seine Case-Statements verloren hat, der hat die Kontrolle über sein Leben verloren. Da hilft auch eine Magic-Number nichts.

#7507205
Lesenswert?

Nuri O. schrieb:

Kann man irgenwie mit einer Funktion während dem Programmverlauf die Anzahl der Cases einer switch-case-Verzweigung herausfinden ?

Wenn dein Programm auf den Sourcecode zugreifen kann, sollte das mit einem stark vereinfachten C++-Parser kein Problem sein.

Was natürlich wie alle anderen Antworten mit Lösungsvorschlägen nichts daran ändert, daß die einzig sinnvolle Antwort nein lautet.

Oliver

#7507226
Lesenswert?

Hannes J. schrieb:

Rolf M. schrieb:

Nein, aber zur Programmierzeit können es mehr oder weniger werden. Und dann ist es geschickt, wenn man nicht jedes mal daran denken muss, noch irgendwo eine magic number anpassen zu müssen.

Wozu soll diese Magic-Number dienen? Das konnte keiner von euch Helden bisher beantworten.

Das hat der TO doch schon geschrieben. Du Held hast es wohl nur überlesen. Sie soll dazu dienen, dem Zufallsgenerator den Zahlenbereich vorzugeben:

Nuri O. schrieb:

Ich erzeuge eine Random zahl und führe dann den entsprechenden Case aus. Dafür muss ich ja wissen wie viele ich habe.

Hannes J. schrieb:

Wer die Kontrolle über seine Case-Statements verloren hat, der hat die Kontrolle über sein Leben verloren. Da hilft auch eine Magic-Number nichts.

Nun, ohne die Magic Number muss man die Anzahl halt programmatisch ermitteln, aber das lehnst du ja auch ab. Mehr Möglichkeiten gibt es nicht.

Persönliche Seite #7507255
Lesenswert?

Wenn dem so ist (z.B. Zufallsgenerator mit N Ergebnissen, etwa "elektronischer" Würfel) dann ist switch-case vermutlich das falsche Mittel:

  • N ändert sich nie → switch / case ist kein Problem

  • N ändert sich zur Compilezeit, d.h. es gibt X Generierungsvarianten für "Würfel" mit unterschiedlich vielen Seiten / Würfelmöglichkleiten. Abhängig vom Problem und davon, wie groß X ist, kann man:

  1. X Generierungsvarianten vorhalten, wenn sich die X's schlecht generalisieren lassen.

  2. Lassen sich die X's gut generalisieren, kann man direkt algorithmisch rangehen, oder auto-Generierung der Codestelle in Betracht ziehen.

  • N ändert sich zur Laufzeit → Ähnlich wie im vorherigen Fall: Bei X möglichen Varianten kann man for jedes mögliche X Code vorhalten (per if-else oder switch-case oder virtuelle Methoden etc); das trifft zu wenn X überschaubar ist. Bei Zillionen von Möglichkeiten für X geht's dann wieder algorithmisch.
#7507740
Lesenswert?

Rolf M. schrieb:

Hannes J. schrieb:

Wozu soll diese Magic-Number dienen? Das konnte keiner von euch Helden bisher beantworten.

Das hat der TO doch schon geschrieben. Du Held hast es wohl nur überlesen. Sie soll dazu dienen, dem Zufallsgenerator den Zahlenbereich vorzugeben:

Nuri O. schrieb:

Ich erzeuge eine Random zahl und führe dann den entsprechenden Case aus. Dafür muss ich ja wissen wie viele ich habe.

Das würde aber voraussetzen, dass die verschiedenen Fälle von 0 bis N fortlaufend numeriert sind – was nun absolut nicht selbstverständlich ist.

Ich würde switch/case z.B. für Verzweigungen in Abhängigkeit von Protokollnummern etc. einsetzen, und da hat man normalerweise nur ein paar interessante Werte und viele Lücken dazwischen.

#7507888
Lesenswert?

Ralf D. schrieb:

Nuri O. schrieb:

Ich erzeuge eine Random zahl und führe dann den entsprechenden Case aus. Dafür muss ich ja wissen wie viele ich habe.

Das würde aber voraussetzen, dass die verschiedenen Fälle von 0 bis N fortlaufend numeriert sind – was nun absolut nicht selbstverständlich ist.

Warum sollte man sie anders nummerieren, wenn der Zweck ist, sie per Zufallsgenerator auszuwählen?

Ich würde switch/case z.B. für Verzweigungen in Abhängigkeit von Protokollnummern etc. einsetzen, und da hat man normalerweise nur ein paar interessante Werte und viele Lücken dazwischen.

Dann braucht man aber auch die Anzahl nicht.

#7507911
Lesenswert?

Arduino F. schrieb:

Jens G. schrieb:

Das hat aber nichts mit einem dynamisch während des Programmlaufs ermittelten Wert zu tun.

Das spielt doch gar keine Rolex, da ein switch/case Konstrukt sowieso nicht zur Laufzeit verändert werden kann.

Egal, ob das eine Rolle spielt - er will die vorhandenen Cases dynamisch zur Laufzeit ermitteln ... ist halt ein Holzweg ...

(Firma: Vescomp) #7507922
Lesenswert?

Nuri O. schrieb:

Ich erzeuge eine Random zahl und führe dann den entsprechenden Case aus. Dafür muss ich ja wissen wie viele ich habe. Hatte mich dann gefragt, ob man das statt händisch auch irgendwie auslesen kann. Villeicht lernt man ja was neues :)

Du willst die Anzahl der erzeugten "Random Zahlen" wissen? Was glaubst du warum es "Random" heisst? Weil beim nächsten Durchlauf wieder genau die selben Zahlen erzeugt werden?

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