2017-02-14 3 views
2

J'ai un problème en traduisant cet organigramme ci-dessous en code C++.Traduire le diagramme en code C++

Flowchart

Il devrait probablement regarder un peu comme ça (je sais que ce qui ne va pas pour l'instant):

do { 
    I1; 
    if(!W1) { 
     I2; 
    ... 
    } 
} 

I1, I2, I3 sont des instructions. Je pense que je devrais utiliser des variables booléennes pour le faire correctement, mais comment?

Répondre

5

Il existe une boucle dans l'organigramme. La condition d'arrêt de la boucle est en fait W1.

while (!W1()) 
{ 
} 

I1 est exécuté (d'abord), peu importe, et est effectué avant l'arrivée de la boucle vérification de l'état, donc nous allons mettre à jour le code:

I1(); 
while (!W1()) 
{ 
} 

Encore une fois, I2 est effectuée uncoditionally:

I1(); 
while (!W1()) 
{    
    I2(); 
} 

Maintenant, W2 affecte si nous exécutons I1 ou I3, mettons à jour le code en conséquence:

I1(); // for the first, unconditional execution 
while (!W1()) 
{ 
    I2(); 
    if (W2()) 
     I1(); 
    else 
     I3(); 
} 
+0

Maintenant, je comprends. Merci. :) –

0

Voici mon idée:

for (bool skip_i1 = false; ; skip_i1 = true) 
{ 
    for (bool w2 = true; w2; w2 = W2()) 
    { 
     if (!skip_i1) { I1(); } 
     skip_i1 = false; 

     if (W1()) { Finish(); return; } 

     I2(); 
    } 

    I3(); 
} 

Il y a deux boucles dans le tableau de flux, nous avons donc deux boucles dans le code, mais parce que le flux de contrôle est « mis emboîtés », nous avons besoin d'un drapeau (skip_i1) pour se ramifier sur le bit de chevauchement. En variante, vous pouvez mettre skip_i1 = false; dans l'incrémenteur for interne ou dans une branche else de l'instruction if.

Je suppose que le code entier vit dans une fonction de son propre (comme il vaut mieux!), De sorte que nous pouvons quitter la boucle interne directement avec return.

1

Vous êtes dans le cas de deux boucles croisées: aucune n'est imbriquée dans l'autre, les outils habituels de contrôle de flux sont donc insuffisants.
Beaucoup les modéliseront généralement avec des drapeaux booléens artificiels, ou dupliqueront une partie du code. Mais c'est en fait l'un des rares (et je veux dire très peu - réfléchir dur au préalable) cas d'utilisation de goto.

Ignorant true branche W2 », cela ressemble à une boucle simple while:

I1; 

while(!W1) { 
    I2; 

    if(W2) 
     /* ? */; 

    I3; 
} 

Maintenant, il suffit d'ajouter la branche manquante. L'étiquette, bien sûr, devrait être nommée adéquatement pour refléter votre logique de domaine réelle. Ajoutez des commentaires pour que tout soit clair et que vous soyez prêt.

// Let's W1 a stuff from our list of stuffs 

handleNextStuff: 

    // Take a stuff 
    I1; 

    // Try W1'ing the stuff. 
    while(!W1) { 
     I2; 

     // No way we can W1 this stuff, drop it and try the next one. 
     if(W2) 
      goto handleNextStuff; 

     // A step closer to a W1'd stuff. 
     I3; 
    } 
+0

Bien que cela ressemble à un cas pratique pour utiliser 'goto', l'introduire pour (très probablement) un programmeur débutant, peut conduire à des problèmes futurs ...Imaginez juste les conséquences si quelqu'un décidait d'encapsuler le corps de 'while 'dans une fonction. – hauron

+1

@hauron Ajout d'un peu de prudence à mon libellé. Si la boucle a un sens en tant que fonction séparée, alors cette fonction aura deux états de retour possibles, qui seront documentés et branchés dans la boucle "externe". En fait, une autre façon de contourner l'utilisation de 'goto' est de générer des fonctions superflues à partir desquelles ils peuvent revenir tôt - mais si la fonction a une raison réelle d'exister, il n'y a pas de problème. – Quentin

0
START: 
I1(); 
while(!W1){ 
    I2(); 
    while(W2) // or if() it's the same... 
     goto START; 
    I3(); 
} 
return; // finish 

J'espère que l'aide