TP Structures de contrôles



Conditionnelles

Les opérateurs de comparaison

Opérateurs sur ChaînesNombres
Égalité eq ==
Différentne !=
Inférieur lt <
Supérieur gt >
Inférieur ou égal le <=
Supérieur ou égal ge >=
Comparaison cmp <= >
Opérateurs logiques
et and, &&
ou or, ||
non !

Les opérateurs de comparaison cmp et <=> pour les chaînes et les nombres renvoient -1, 0 ou 1 selon que le premier argument est inférieur, égal ou supérieur au second.

Utilisation des opérateurs en tant que structure de contrôle

Les opérateurs logiques sont évalués de façon "paresseuse" : si le 1er opérande détermine le résultat, le second est ignoré. Cette facilité déroutante qui dérive de la programmation shell (BASH) est très utilisée.
Exemples :
# façon de dire : "ouvre ce fichier ou arrete-toi !"
open F, "fichier.txt" or die "impossible d'ouvrir le fichier\n";
# au lieu de dire : print "le nombre $a est pair" if $a%2==0;
$a%2==0 and print "le nombre $a est pair";

Structures conditionnelles if et unless

Instruction conditionnelle

Il s'agit d'une forme particulière de conditionnelle. L'évaluation de la condition conduit au calcul d'une expression différente, selon que la condition est vraie ou fausse, dont la valeur est retournée
Syntaxe
$variable = condition? expression si vrai:expression si faux;
Exemples :
$sup = $a>$b? $a:$b;
print "Le plus grand de $a et de $b est $sup\n";

print "Combien d'enfants ? ";
$nb=<>; chomp($nb);
$pluriel= $nb > 1? "s": "";
print "J'ai $nb enfant$pluriel\n";

Structures itératives while, until et do

Structures itératives for et foreach

Contrôle de boucle : last et next

next dans un bloc de boucle, ordonne de passer tout de suite à l'itération suivante, en ignorant les éventuelles instructions restantes
# parcourir un fichier et sauter les lignes commentaires
# commençant par l'un des symboles # ou ;
open F, "/var/log/httpd/access_log";
while ($ligne = <F>) {
 next if ($ligne =~ /^[#;]/);
}
last interrompt inconditionnellement l'exécution de la boucle, et passe à la fin du bloc.
# exemple : saisie d'une liste de mots jusqu'à la saisie de "quit"
while ($mot = <>) {
 chomp($mot);
 last if ($mot eq "quit");
 # remarquer que le dernier mot "quit" n'est pas empilé !
 push @mots, $mot;
}
print "liste des mots = @mots\n";

Les fonctions

  TP

################## Etude des (pseudo)booléens ###################

Expliquez et expérimentez :
#!/usr/bin/perl -w
# contexte.pl
$x = 0;
print ($x ? "vrai\n": "faux\n");
$x = "";
print ($x ? "vrai\n": "faux\n");
@x = ();
print (@x ? "vrai\n": "faux\n");
my $x;
print ($x ? "vrai\n": "faux\n");

################### Aire d'un carré et d'un rectangle ####################

Ecrire le script carre.pl, contenant une petite fonction carre qui attend un paramètre (la longueur du coté) et qui retourne son aire, ainsi qu'un programme pour appeler cette fonction.
Prolongement
Le script rectangle.pl doit contenir une fonction qui reçoit les 2 paramètres longueur et largeur et doit retourner l'aire et le périmètre. Pensez à retourner ces 2 résultats sous forme d'une liste.

################# Saisie d'un mot de passe ##################

Version 1 (motpasse.pl) Version 2 (motpasse2.pl) -----------------------------------------------
#!/usr/bin/perl -w
$N=3;
print "Trouvez le mot de passe, $N essais maximum\n";

# variante : on pourrait stocker le mot de passe dans un fichier
$secret="perl";
$mdpc = crypt($secret,"pe");

# compteur du nombre d'essais
$i=0;
# indique si le mot de passe a bien été trouvé
$trouve = 0;
do {
 $i++;
 print "Essai numéro ... : donnez le mot de passe  --> ";
 $mot=  <>;
 chomp($mot);
 $motc  = crypt($mot,"pe");
 print $motc,"\n";
 $trouve =1 if ......
 } while ...........;

if (......) {
  print "Mot de passe trouvé à la tentative numéro $i, bienvenue !\n";
  }
  else {
  print "Mot de passe non trouvé, au revoir ...\n";
}

################## Simulation de lancers de dé ##################

Le script hasard.pl est destiné à simuler le lancer d'un dé usuel

############## Lister les premiers nombres premiers ################

  1. premier1.pl, version de base
    Voir au-dessous l'affichage souhaité lors d'une exécution :
    • le nombre 20 a été saisi par l'utilisateur
    • le programme construit une liste des nombres premiers
    • naturellement on n'étudiera que les nombres impairs, à partir de 3,
    • la recherche des éventuels diviseurs s'arretera à la racine carré du nombre
    • on pourra comparer les performances avec les façons usuelles de construire une liste (pour la liste des nombres premiers)
    # ./premier1.pl
    Recherche des nombres premiers jusqu'a N = 20
    5 est premier
    7 est premier
    9 = 3 x 3
    11 est premier
    13 est premier
    15 = 3 x 5
    17 est premier
    19 est premier
    Liste des nombres premiers jusqu'a 20
    2 3 5 7 11 13 17 19
    
  2. Version premier2.pl
    Afin de rationnaliser la recherche*, et accélérer l'exécution, on peut se contenter d'utiliser dans la recherche d'éventuels diviseurs, les premiers éléments de la liste des nombres premiers déjà construite. Ainsi, le nombre d'essais sera considérablement réduit
    (* il est stupide d'essayer le diviseur 15 par exemple, (et tous les multiples de 3) à partir du moment où l'essai du diviseur 3 a échoué !)
  3. Version premier3.pl
    En utilisant la liste des nombres premiers déjà trouvés et qui a été sauvegardée dans un fichier.
    Dans la perspective de conserver de façon permanente la liste des nombres premiers déjà trouvés, on a recours à un fichier. A chaque exécution du programme, la liste est chargée en mémoire, et si nécessaire complétée.