Forum: Compiler & IDEs if bedingung vereinfachen


von andy (Gast)


Lesenswert?

Hallo,ich habe hier ein Programm,welches auch einwandfrei läuft.
In einer schleife wird folgende if bedingung bei jedem durchlauf 
ausgewertet.

if(zaehler > 21 & zaehler < 26 || zaehler > 31 & zaehler < 36 || zaehler 
> 41 & zaehler < 46 || zaehler > 51 & zaehler < 56)
   {
      anzeige [5] [0] = anzeige [5] [0] << 1;
      anzeige [4] [0] = anzeige [4] [0] << 1;
      anzeige [3] [0] = anzeige [3] [0] << 1;
      anzeige [2] [0] = anzeige [2] [0] << 1;

     }

if(zaehler > 26 & zaehler < 31 || zaehler > 36 & zaehler < 41 || zaehler 
> 46 & zaehler < 51 || zaehler > 56 & zaehler < 61)
   {
      anzeige [5] [0] = anzeige [5] [0] >> 1;
      anzeige [4] [0] = anzeige [4] [0] >> 1;
      anzeige [3] [0] = anzeige [3] [0] >> 1;
      anzeige [2] [0] = anzeige [2] [0] >> 1;
     }
zaehler wird in jedem durchlauf um 1 erhöht.Da mein zaehler vergleich 
bis 200 so fortgeführt werden soll,gibt das lange bedingungen.
Ich sitze hier schon einige Zeit und überlege,wie man das einfacher 
hinbekommen kann,komme aber auf nichts.Hat vielleicht jemand einen Tip?.

gruss

andy

von Stephu (Gast)


Lesenswert?

Ein paar for loops verwenden.... Was willst du genau machen. Evlt. geht 
das ganze einfacher....

von Karl H. (kbuchegg)


Lesenswert?

das zweite if sieht so aus als ob es das Gegenteil vom ersten wäre. Wie 
die Sache bei zaehler < 22 ist bzw über 60 musst du wissen, aber ich 
vermute mal, dass das ganze erst mal ein Fall für einen else ist.

   if( Bedinung )
     ...
   else
     ...


damit spart man sich schon mal die 2. te Bedinung. Der else Zweig 
behandelt automatisch alle Fälle die nicht von der Bedinung abgedeckt 
sind.

Dann: Das sieht so aus, als ob es die Bedingung davon abhängt, wie die 
Einerstelle deines zahlers aussieht: von 2 bis 5, ist es der eine Faall; 
von 6 bis 1 der andere.

Die Einerstelle kriegt man aber leicht

  einer = zaehler % 10;

  if( einer > 1 && einer < 6 ) {
      anzeige [5] [0] = anzeige [5] [0] << 1;
      anzeige [4] [0] = anzeige [4] [0] << 1;
      anzeige [3] [0] = anzeige [3] [0] << 1;
      anzeige [2] [0] = anzeige [2] [0] << 1;
  }
  else {
      anzeige [5] [0] = anzeige [5] [0] >> 1;
      anzeige [4] [0] = anzeige [4] [0] >> 1;
      anzeige [3] [0] = anzeige [3] [0] >> 1;
      anzeige [2] [0] = anzeige [2] [0] >> 1;
 }

ob das jetzt alles 100% bei dir so einsatzbar ist oder nicht, kann man 
anhand eines einzelnen kleinen Codeausshcnitts so nicht sagen. Eventuell 
sind da noch ein paar Modifikationen notwendig, aber ich denke soweit 
liegt das nicht daneben.

von Stephu (Gast)


Lesenswert?

Noch ein bisschen kürzen

for(i = 5,  i > 1, i--)
  {
  anzeige [i] [0] = anzeige [i] [0] << 1;
  }

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ich glaub nicht, daß du & in den Bedingungen willst. Vielmehr wohl &&, 
oder?

In ersten Vergleich ist zähler / 10 = 2..4 und zähler % 10 = 2..5, 
allerdings glaube ich nicht, daß du mit Divisionsn anfanngen willst 
wenn's dir um Effizienz geht.

Anstatt eine if-Bedingung zu schreiben geht auch ein switch, so daß der 
Compiler das in einen binären Entscheidungsbaum aufdröseln kann (GNU-C). 
Das ist effizienter als das Rumgeturne mit div und mod auch wenn's nicht 
so elegant aussieht:
1
switch (zaehler)
2
{
3
   case 22 ... 25:
4
   case 32 ... 35:
5
   case 42 ... 45:
6
7
     anzeige[5][0] <<= 1;
8
     anzeige[4][0] <<= 1;
9
     anzeige[3][0] <<= 1;
10
     anzeige[2][0] <<= 1;
11
      
12
     break;
13
}

Möglicherweise ist es aber einfach ungeschickt, zähler als Skalar zu 
führen anstatt ihn zB in 2 Variablen aufzuspalen, zB in Zehner und 
Einer.

von Karl H. (kbuchegg)


Lesenswert?

Johann L. schrieb:

> Möglicherweise ist es aber einfach ungeschickt, zähler als Skalar zu
> führen anstatt ihn zB in 2 Variablen aufzuspalen, zB in Zehner und
> Einer.

Das ist eine gute Idee. Die sollte andy unbedingt im Auge behalten!

von --- (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Dann: Das sieht so aus, als ob es die Bedingung davon abhängt, wie die
> Einerstelle deines zahlers aussieht: von 2 bis 5, ist es der eine Faall;
> von 6 bis 1 der andere.

Fast, bei 1 und 6 trifft keiner der beiden Fälle zu. Vorrausgesetzt 
natürlich, daß das binäre UND da tatsichlich ein Tippfehler ist.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Habe eben mal folgenden Code durch avr-gcc 4.6 durchgelassen:
1
char a;
2
3
void foo (unsigned char z)
4
{
5
    switch (z)
6
    {
7
    case 22 ... 25:
8
    case 32 ... 35:
9
    case 42 ... 45:
10
        
11
        a = 0;
12
        break;
13
    }
14
}
Für einen ATmega8 mit -Os gibt das:
1
foo:
2
  cpi r24,lo8(36)
3
  brsh .L4
4
  cpi r24,lo8(32)
5
  brsh .L3
6
  subi r24,lo8(-(-22))
7
  rjmp .L6
8
.L4:
9
  subi r24,lo8(-(-42))
10
.L6:
11
  cpi r24,lo8(4)
12
  brsh .L1
13
.L3:
14
  sts a,__zero_reg__
15
.L1:
16
  ret
Sieht doch sehr gut aus!

von andy (Gast)


Lesenswert?

hallo,vielen dank für die antworten.Ich schaue stundenlang drauf und 
sehe es nicht.Das mit dem auswerten der einerstellen ist einerstellen 
ist genial,peinlich das ich nicht selber drauf gekommen bin.
Nochmals vielen dank.

gruss

andy

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.