mikrocontroller.net

Forum: Compiler & IDEs if-Verzweigung optimieren


Autor: Onan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

habe folgende Verzweigung:

if (a == 1)
{
  x= 10;
  DoSomething;
} else if (a == 2)
  {
    x= 20;
    DoSomething;
  }
  else
  {
   /* Programm zu Ende */
  }


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:
if ((a == 1) || (a == 2))
{
  DoSomething;
  if ( a == 1)
  { x = 10 }
  if (a == 2)
  { x = 20 }
}

Gibt es eine geschicktere Möglichkeit?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Armin Zensiert (Firma: spengergasse) (mors)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Onan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
a=0;
switch(a)
{
  case 2:    a=10;
  case 1:    a+=10;
             DoSomething;
             break;
      
  default:   // ...
}

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder noch einfacher und ohne Verschreiber:
switch(x=10, a)
{
  case 2:    x=20;
  case 1:    DoSomething;
             break;

  default:   // ...
}

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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe 2. Beispiel ;). Wobei im allg. Fall
if (a == ca)
{
  x= va;
  DoSomething;
} else if (a == cb)
  {
    x= vb;
    DoSomething;
  }
  else
  {
   /* Programm zu Ende */
  }


natürlich auch
switch(x=va, a)
{
  case cb:   x+=vb-va;
  case ca:   DoSomething;
             break;
      
  default:   // ...
}

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.