Forum: Mikrocontroller und Digitale Elektronik Alternative um Schleifeniteration zu wiederholen


von pc (Gast)


Lesenswert?

Hallo,

aktuell habe ich in meinem Programm öfters den unten dargestellten 
Ablauf.

Das Manipulieren des Iterators im Schleifenablauf scheint mir nicht ganz 
geschickt. Kennt einer eine besser alternative zu dem Konstrukt?


Pseudocode:
1
for(i=1; i<= MAX_ANZ_BUSTEILNEHMER; i++){
2
3
    ret = ping_teilnehmeradresse(i); 
4
5
    if(ret != 0){
6
        // Ok, Teilnehmer erreicht, mache xyz
7
    }
8
    else {
9
        // Teilnehmer nicht erreicht, probiere nochmal
10
        i--;
11
        retryCounter++; 
12
        if(retryCounter > MAX_RETRIES) break; 
13
14
    }
15
}
16
17
//...

von Sebastian R. (sebastian_r569)


Lesenswert?

In der For-Schleife noch eine While-Schleife mit Antwort oder maximale 
Anzahl der Versuche erreicht als Abbruchbedingung?
1
for(i=1; i<= MAX_ANZ_BUSTEILNEHMER; i++){
2
3
    retryCounter = 0;
4
5
    do{
6
         ret = ping_teilnehmeradresse(i); 
7
         retryCounter++;
8
      }while((ret == 0) && (retryCounter > MAX_RETRIES))
9
10
11
}

Oder so ähnlich?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

pc schrieb:
> Das Manipulieren des Iterators im Schleifenablauf scheint mir nicht ganz
> geschickt.
Ich würde es so machen, dann kommt die Manipulation des Index nicht so 
"hinterrückwärts". Sondern man sieht sofort, dass der Index irgendwo 
anders verändert wird:
1
for(i=1; i<= MAX_ANZ_BUSTEILNEHMER; ){
2
3
    ret = ping_teilnehmeradresse(i); 
4
5
    if(ret != 0){
6
        // Ok, Teilnehmer erreicht, mache xyz
7
        i++;
8
    }
9
    else {
10
        // Teilnehmer nicht erreicht, probiere nochmal
11
        retryCounter++; 
12
        if(retryCounter > MAX_RETRIES) break; 
13
    }
14
}


pc schrieb:
> Kennt einer eine besser alternative zu dem Konstrukt?
In der Hauptschleife wird ein Teilnehmer nach dem anderen 
gepingt/gepollt und die Anwesenden/Aufgefundenen in eine Liste 
eingetragen. Dort kann dann ein anderer Programmteil nachsehen, wer 
schon alles da ist und ggfs. eine entsprechende Meldung generieren.

von Falk B. (falk)


Lesenswert?

pc schrieb:
> Das Manipulieren des Iterators im Schleifenablauf scheint mir nicht ganz
> geschickt. Kennt einer eine besser alternative zu dem Konstrukt?

Sicher.
1
 
2
for(i=1; i<= MAX_ANZ_BUSTEILNEHMER; i++){
3
    for(retryCounter=0, ret=0; retryCounter<RETRY_MAX && ret==0; retryCounter++) {
4
        ret = ping_teilnehmeradresse(i);
5
    }    
6
    if(ret==0) break;
7
}

von Nick M. (Gast)


Lesenswert?

> Das Manipulieren des Iterators im Schleifenablauf scheint mir nicht ganz
> geschickt

Ist vor allem mWn nach nicht zulässig.
Zweite innere for-Schleife oder wie oben gesagt ein while.
Oder das ganze als State-Machine, insbesondere, wenn noch andere 
Befindlichkeiten der BUSTEILNEHMER zu erwarte sind.

Oder noch sauberer, die Behandlung eines einzelnen Busteilnehmers in ein 
Funktion reinpacken.

Nick

von pc (Gast)


Lesenswert?

Danke für die flotten Antworten. Ich werde das mal auf die innere 
do-while-Schleife umbauen.

Nick M. schrieb:
> Oder das ganze als State-Machine, insbesondere, wenn noch andere
> Befindlichkeiten der BUSTEILNEHMER zu erwarte sind.

Das klingt auch interessant. Hast du ein Pseudocode-Beispiel?

von Nick M. (Gast)


Lesenswert?

1
typedef enum {
2
  sInit,
3
  sDeviceGet,
4
  sDeviceRetry,
5
  sDeviceAbort,
6
  sDeviceNext
7
} deviceStates_t;
8
9
deviceStates_t state = sInit;
10
int deviceNum;
11
bool scanning = true;
12
13
while (scanning) {
14
  switch (state) {
15
    case sInit:
16
      deviceNum = -1;
17
      state = sDeviceNext;
18
      break;
19
20
    case sDeviceNext:
21
           deviceNum += 1;
22
           if (deviceNum > XYZ)
23
             scanning = false;
24
           else
25
             state = sDeviceGet;
26
      break;
27
28
    case sDeviceGet: {
29
       int ret = ping_teilnehmeradresse(deviceNum );
30
        if (ret != 0) {
31
           // ...
32
           state = sDeviceNext;
33
        }
34
        else
35
          state = sDeviceRetry;
36
        break;
37
        }
38
39
   case sDeviceRetry:
40
        ....
41
        sDeviceNext oder sDeviceAbort
42
        ...
43
        break;
44
45
   case sDeviceAbort:
46
         state = sDeviceNext;
47
        break;
48
}

Ohne syntax-check!

von Dumpfbacke (Gast)


Lesenswert?

Nick M. schrieb:
> Ist vor allem mWn nach nicht zulässig.

Dann würde es der Compiler abweisen.
Nein, das ist zulässig.

For(i=1; i<10; i++) {Befehle();} ist auch "nur" eine Abkürzung für:
1
i=1;
2
while(i<10) {
3
  Befehle();
4
  i++;
5
}

von Nick M. (Gast)


Lesenswert?

> Dann würde es der Compiler abweisen.
> Nein, das ist zulässig.

Hab den Standard nicht da.
Jedenfalls verbieten es genügend Sprachen um das als eindeutig "bad 
coding style" einzuordnen.

Nick

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.