Forum: Compiler & IDEs if-Verzweigung optimieren


von Onan (Gast)


Lesenswert?

Hallo,

habe folgende Verzweigung:
1
if (a == 1)
2
{
3
  x= 10;
4
  DoSomething;
5
} else if (a == 2)
6
  {
7
    x= 20;
8
    DoSomething;
9
  }
10
  else
11
  {
12
   /* Programm zu Ende */
13
  }

DoSomething sind Aktionen, die beide Zweige ausführen sollen. Die 
Aktionen benötigen also ( a==1) || (a == 2)

Ich möchte DoSomething aber nicht als Funktion einbauen. Wie kann ich es 
am sinnvollsten erreichen, dass ich den Code von DoSomething nicht 
zweimal abtippen muss?

Mir fällt spontan nur ein:
1
if ((a == 1) || (a == 2))
2
{
3
  DoSomething;
4
  if ( a == 1)
5
  { x = 10 }
6
  if (a == 2)
7
  { x = 20 }
8
}

Gibt es eine geschicktere Möglichkeit?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Geschickter im Sonn von lesbarer, dann vielleicht

if ((a == 1) || (a == 2))
{
  x = a * 10;  // vor DoSomething, wenn es dem 1. Code entsprechen soll
  DoSomething;
}

Ausführungstechnisch dürfte es keinen grossen Unterschied zu deiner 2. 
Variante machen.

Es ginge auch

if ((a == 1) || (a == 2))
{
  x = 10;  // vor DoSomething, wenn es dem 1. Code entsprechen soll
  if (a == 2) x += 10;
  DoSomething;
}

Oder wenn a nicht mehr gebraucht wird

if ((a == 1) || (a == 2))
{
  x = 0;
  while (a--)
    x += 10;
  DoSomething;
}

Und so weiter...

von Michael Wilhelm (Gast)


Lesenswert?

In deiner 2. Version kann die Abfrage
if(a == 2)
umgeformt werden in eine else-Verzweigung von if(a == 1), da ja nur bei 
a == 1 oder 2 reingesprungen wird.

MW

von Armin Z. (Firma: spengergasse) (mors)


Lesenswert?

Wie wäre es mit einem Switch?
evtl. hast dann nochmals in einer Methode/Funktion die du dann aufrufst 
wenn a oder b zutrifft, in den parametern den wert 10 bzw. 20 stehen


switch(zahlZuUeberpruefen)
{
  case 1:
    METHODENAUFRUF(10);

/*^^Wenn die Variabel "zahlZuUeberpruefen" gleich dem Wert vom case hat 
wird dieser eben ausgewählt und dann wird die darauf folgende Anweisung 
ausgeführt*/

  default:
    ANWEISUNG;

/*^^Statt default solltest du denke ich auch einfach "case 2" nehmen 
können, sonst bleibt alles gleich, default bedeutet eben einfach nur, 
wenn der Rest nicht zutrifft macht er den Standart durch.*/
}

hoffe ich hab dir helfen können bzw. ich hab dir nix falsches gesagt.


EDIT: bei DEINEM 2ten Vorschlag ist das iwie unlogisch wieso du 2x 
abprüfst du kannst da dann in dem Fall die äußere Abfrage komplett raus 
lassen und die beiden anderen dafür abfragen lassen

von Onan (Gast)


Lesenswert?

>EDIT: bei DEINEM 2ten Vorschlag ist das iwie unlogisch wieso du 2x
>abprüfst du kannst da dann in dem Fall die äußere Abfrage komplett raus
>lassen und die beiden anderen dafür abfragen lassen

Les mein Posting nochmal richtig ;) Wenn ich die äußere Abfrage komplett 
rauslasse, muss ich DoSomething in beide Zweige tippen. Will ich aber 
nicht.

>Geschickter im Sonn von lesbarer, dann vielleicht
>
>if ((a == 1) || (a == 2))
>{
>  x = a * 10;  // vor DoSomething, wenn es dem 1. Code entsprechen soll
>  DoSomething;
>}

die Werte für a und x sind Beispiele. Im realen Code wird x jeweils eine 
Konstante zugewiesen, mit arithmetischen Operationen ist da nichts zu 
machen.

>In deiner 2. Version kann die Abfrage
>if(a == 2)
>umgeformt werden in eine else-Verzweigung von if(a == 1), da ja nur bei
>a == 1 oder 2 reingesprungen wird.

Stimmt. Ist das dann Prozessortechnisch optimaler?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wenn du schon keine Funktion nehmen willst (warum nicht?  kann man ja
auch inline machen), kannst du DoSomething allemal in einen Makro
hacken.  Sieht nicht sehr schön aus, aber funktioniert.

von I_ H. (i_h)


Lesenswert?

1
a=0;
2
switch(a)
3
{
4
  case 2:    a=10;
5
  case 1:    a+=10;
6
             DoSomething;
7
             break;
8
      
9
  default:   // ...
10
}

von I_ H. (i_h)


Lesenswert?

Oder noch einfacher und ohne Verschreiber:
1
switch(x=10, a)
2
{
3
  case 2:    x=20;
4
  case 1:    DoSomething;
5
             break;
6
7
  default:   // ...
8
}

Dafür nicht ganz so mächtig (wollte man zB. auch noch 3 behandeln, dann 
müsste wieder += her).

von Stefan E. (sternst)


Lesenswert?

@ I_ H.:

Der OP hat doch schon geschrieben:
> die Werte für a und x sind Beispiele. Im realen Code wird x jeweils eine
> Konstante zugewiesen, mit arithmetischen Operationen ist da nichts zu
> machen.

von I_ H. (i_h)


Lesenswert?

Siehe 2. Beispiel ;). Wobei im allg. Fall
1
if (a == ca)
2
{
3
  x= va;
4
  DoSomething;
5
} else if (a == cb)
6
  {
7
    x= vb;
8
    DoSomething;
9
  }
10
  else
11
  {
12
   /* Programm zu Ende */
13
  }

natürlich auch
1
switch(x=va, a)
2
{
3
  case cb:   x+=vb-va;
4
  case ca:   DoSomething;
5
             break;
6
      
7
  default:   // ...
8
}

funktioniert, was dann auch auf beliebig viele Fälle erweiterbar ist. 
Die Konstantenrechnungen werden eh wegoptimiert.

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.