if-Anweisungen als Block

OP #5244325
Lesenswert?

Hallo.
Vesuche Prog (C) zu optimieren, daher die Frage ob folgende Routine 
"legetim" ist;
______________________________________
SprungZiel = 0;
if (LadSpg_ON) SprungZiel=2; // wenn Ladespg vorhanden
if ((PORTA & (1<<PA4)) == 0) SprungZiel=2; // wenn PORT_BATT_OUT low
if ((PINB & (1<<PB0)) != 0) SprungZiel=1; // wenn Eing. SPERRE_IN high

switch(SprungZiel)
{
case 1:  // SPERRE_IN high
...
break;

case 2: // PORT_BATT_OUT high
...
break;

default: // weitere Messung, Auswertung, Steuerung
...
break;
}
_________________________________________

Verständnisfrage:
Das Prog. durchläuft zwingend(?!) alle 3 if-Aweisungen nacheinander.
Sobald einer der 3 if-Anweisungen "wahr" ist, verändert sich die 
Variable "SprungZiel" auf 1 oder 2.
(Firma: Flk Consulting UG) #5244347
Lesenswert?

Hallo,
die Frage ist mit JaEin zu beantworten.

Wenn eine der beiden ersten Anweisungen SprungZiel = 2 gesetzt haben, 
darf dann trotzdem noch SprungZiel = 1 angesprungen werden?

Die beiden ersten Anweisung kannst Du zusätzlich zu einem if 
zusammenfassen und die beiden Entscheidungen oder verknüpfen.
1
if (LadSpg_ON || (PORTA & (1<<PA4) == 0)) SprungZiel=2;

Gruß
Frank
#5244348
Lesenswert?

Hallo,

also so ganz toll finde ich diesen Programmierstil nicht:

Wenn im oberen Teil mehrere Bedingungen true sind, wird SprungZiel 
mehrfach zugewiesen. Nur das letzte wird dann tatsächlich ausgeführt.

Intuitiv würde ich in der if then - Kette erwarten, dass die wichtigsten 
Bedingungen zuerst notiert sind.

Ungewöhnlicher Programmierstil und eine wenig intuitive Vorgehensweise 
können zu Fehlern führen, falls sich mal ein Kollege dran betätigen 
muss.

Lösung: man könnte oben if then else if then else abprüfen, dann wäre 
Sprungziel wieder das intuitive Ergebnis.

Gruß,
Michael
#5244350
Lesenswert?

@__Son´s Bersi__ (bersison)

>Vesuche Prog (C) zu optimieren,

Weißt du überhaupt, wie man das richtig macht? Und warum?

https://www.mikrocontroller.net/articles/AVR-GCC-Codeoptimierung#Prinzipien_der_Optimierung

>daher die Frage ob folgende Routine
>"legetim" ist;

Sie ist OK, optimiert aber nichts wirklich. Dein Programm wird weder 
kürzer, noch schneller, noch besser lesbar. Wenn man schon viele 
verschiedene Bedingungen prüfen muss, ist eine if/else Kette sinnvoller. 
Deine Version ist doppelt gemoppelt.
1
if (LadSpg_ON || !((PORTA & (1<<PA4)) ) {
2
  // mach was
3
} else if ((PINB & (1<<PB0)) ) {
4
  // mach was anderes
5
}

>Das Prog. durchläuft zwingend(?!) alle 3 if-Aweisungen nacheinander.

Sicher, es gibt ja keinen else-Zweig.
Gast #5244353
Lesenswert?

__Son´s B. schrieb:
> SprungZiel = 0;
> if (LadSpg_ON) SprungZiel=2; // wenn Ladespg vorhanden
> if ((PORTA & (1<<PA4)) == 0) SprungZiel=2; // wenn PORT_BATT_OUT low
> if ((PINB & (1<<PB0)) != 0) SprungZiel=1; // wenn Eing. SPERRE_IN high

Frank Link hat es schon angedeutet.
Wenn LadSpg_ON wahr ist, dann kann ja trotzdem PB0 != 0 sein. SprungZiel 
wird dann zunächst auf 2 gesetzt und dann aber auf 1. Ist das dein 
Wunsch?

Oft ist es sinnvoll, in den eigentlichen case-Blöcken den 
Switchparameter (SprungZiel) neu zu setzen für den nächsten State.
Zugegeben, ich habe nicht versucht zu überlegen (es fehlen auch Infos 
dazu), was diese Abläufe tun sollen.
Gast #5244354
Lesenswert?

Falk B. schrieb:
> ist eine if/else Kette sinnvoller

Ich mag keine tief geschachtelten if Dinger, mit komplizierten 
Bedingungen.

Persönliche Ansicht: Je naiver, desto besser.

----
Wenn das ein endlicher Automat sein soll, dann sollte man die Schritte 
klar benennen, und die Weiterschaltbedingungen, dahin tun, wo sie 
hingehören, in die Case Bereiche..
OP #5244374
Lesenswert?

HildeK schrieb:
> Frank Link hat es schon angedeutet.
> Wenn LadSpg_ON wahr ist, dann kann ja trotzdem PB0 != 0 sein. SprungZiel
> wird dann zunächst auf 2 gesetzt und dann aber auf 1. Ist das dein
> Wunsch?

Ja!
Die Abfolge ist von oben herab umgekehrt Priorisiert.
D.h., dass die unterste if-Abfrage die Wichtigste ist (Notaus-Meldung).

Auf "else-Verschachtelungen" wollte ich aufgrund einfacherer/schnellerer 
Lesbarkeit (einfache Listenansicht) verzichten.
#5244387
Lesenswert?

__Son´s B. schrieb:
> Auf "else-Verschachtelungen" wollte ich aufgrund einfacherer/schnellerer
> Lesbarkeit (einfache Listenansicht) verzichten.

Else bedeutet nicht zwangsläufig, daß man etwas verschachtelt und es 
schwerer lesbar wird. Dein Verzicht bedeutet aber, daß man den Sinn 
nicht erkennt.
1
if (LadSpg_ON) SprungZiel=2; // wenn Ladespg vorhanden
2
if ((PORTA & (1<<PA4)) == 0) SprungZiel=2; // wenn PORT_BATT_OUT low
3
if ((PINB & (1<<PB0)) != 0) SprungZiel=1; // wenn Eing. SPERRE_IN high

Wenn du priosieren willst dann mach das so
1
if ((PINB & (1<<PB0)) != 0) SprungZiel=1; // wenn Eing. SPERRE_IN high
2
else if ((PORTA & (1<<PA4)) == 0) SprungZiel=2; // wenn PORT_BATT_OUT low
3
else if (LadSpg_ON) SprungZiel=2; // wenn Ladespg vorhanden

Damit erreichst du das gleiche und jedem ist klar, was das soll. Und 
schneller geht es auch noch. Die Zusammenfassung der beiden letzten 
Bedingungen habe ich mir jetzt mal erspart. Die fasst der Compiler auch 
von sich aus zusammen.
(Firma: brickwedde.dev) #5244406
Lesenswert?

Und jetzt noch den Reset von SprungZiel in den "finalen" else Zweig:
1
if ((PINB & (1<<PB0)) != 0) SprungZiel=1; // wenn Eing. SPERRE_IN high
2
else if ((PORTA & (1<<PA4)) == 0) SprungZiel=2; // wenn PORT_BATT_OUT low
3
else if (LadSpg_ON) SprungZiel=2; // wenn Ladespg vorhanden
4
else SprungZiel=0;
#5244419
Lesenswert?

__Son´s B. schrieb:
> Hallo.
> Vesuche Prog (C) zu optimieren, daher die Frage ob folgende Routine
> "legetim" ist;

Es kompiliert, es stürzt zur Laufzeit nicht ab, also: Ja.

> Verständnisfrage:
> Das Prog. durchläuft zwingend(?!) alle 3 if-Aweisungen nacheinander.
> Sobald einer der 3 if-Anweisungen "wahr" ist, verändert sich die
> Variable "SprungZiel" auf 1 oder 2.

Und wo ist die Frage?

Optimaler wäre eher:
1
if ((PINB & (1<<PB0)) != 0)        // wenn Eing. SPERRE_IN high
2
{
3
   ... Code von case 1...
4
}
5
else if ((LadSpg_ON)               // wenn Ladespg vorhanden
6
     || ((PORTA & (1<<PA4)) == 0)) // wenn PORT_BATT_OUT low
7
{
8
  ...Code von case 2...
9
}
10
else 
11
{
12
  ...Code von Default... // weitere Messung, Auswertung, Steuerung
13
}
OP #5244513
Lesenswert?

Erst einmal DANK an alle inspireierenden Anregungen!

Ich mag die Listenarbeiten lieber als Versachachtelungen, daher finde 
ich if-Blöcke und anschliessend switch-Blöcke übersichtlicher.
GESCHMACKSSACHE!

Werde aber zukünftig if/else-Formen wahren;

SprungZiel=0
if ((PINB & (1<<PB0)) != 0) SprungZiel=1; // wenn Eing. SPERRE_IN high
else if ((PORTA & (1<<PA4)) == 0) SprungZiel=2; // wenn PORT_BATT_OUT 
low
else if (LadSpg_ON) SprungZiel=2; // wenn Ladespg vorhanden

else SprungZiel=0;  // überflüssig, da am Schleifenanfang "0" gesetzt 
wird
#5244542
Lesenswert?

__Son´s B. schrieb:
> Werde aber zukünftig if/else-Formen wahren;

...und für Variabelen sinnvolle Namen benutzen, z.B. "Aktion" statt 
"Sprungziel", und bedeutungsvolle Namen definieren für Konstanten, oder 
sogar eine enum dafür!
1
typedef enum {
2
  DO_NOTHING = 0,
3
  BAKE_CAKE,
4
  SWITCH_OFF_OVEN,
5
  WAIT
6
} Action_e;
7

8
Action_e action = DO_NOTHING;
9

10
#define SPERRE_IN_HIGH ((PINB & (1<<PB0))
11
#define BATT_OUT_LOW   (!(PORTA & (1<<PA4)))
12

13
...
14
if (SPERRE_IN_HIGH)
15
  action = BAKE_CAKE;
16
else if(BATT_OUT_LOW || LadSpg_ON)
17
  action = SWITCH_OFF_OVEN;
18
else
19
  action = DO_NOTHING;
20

21
Switch(action) {
22
  case BAKE_CAKE:
23
  ...
24
  break;
25

26
...usw...
#5244554
Lesenswert?

__Son´s B. schrieb:
> Erst einmal DANK an alle inspireierenden Anregungen!

Moooment! ;-)
Wenn ich mich nicht irre, stimmen die vorgeschlagenen Lösungen nicht mit 
der ursprünglichen Anforderung überein:

__Son´s B. schrieb:
> D.h., dass die unterste if-Abfrage die Wichtigste ist (Notaus-Meldung).

Peter D. schrieb:
> if ((PINB & (1<<PB0)) != 0)
>   return 1;
Eric B. schrieb:
> Optimaler wäre eher:if ((PINB & (1<<PB0)) != 0)        // wenn Eing.
> SPERRE_IN high
> {
>    ... Code von case 1...

Sobald die erste Bedingung erfüllt ist, wird auch der dazugehörige Code 
ausgeführt. Das 'Notaus' ist irgendwo gaaaanz weit hinten im 'else' 
versteckt. Also für alle Bedingungen keine Priorisierung wie gefordert.
#5244604
Lesenswert?

@__Son´s Bersi__ (bersison)

>Ich mag die Listenarbeiten lieber als Versachachtelungen, daher finde
>ich if-Blöcke und anschliessend switch-Blöcke übersichtlicher.
>GESCHMACKSSACHE!

Naja, wenn du das in (semi)professionellem Umfeld anwenden willst, ist 
es das nicht, denn andere Leute müssen damit klar kommen. Und das wird 
den Wenigsten gefallen.

Außerdem geht das schon leicht in Richtung Josef'scher "Logik", Mr. Bo8

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