Alternative um Schleifeniteration zu wiederholen

Gast #5982395
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
//...
#5982402
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?
Moderator (Firma: Titel) Persönliche Seite #5982406
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.
#5982409
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
}
Gast #5982414
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
Gast #5982439
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?
Gast #5982464
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!

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