Obligement - L'Amiga au maximum

Mardi 23 mai 2017 - 16:48  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Hit Parade
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles in other languages


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Moteurs de recherche
 · Pages de liens
 · Constructeurs matériels
 · Matériel
 · Autres sites de matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Développeurs logiciels
 · Logiciels
 · Développeurs de jeux
 · Jeux
 · Autres sites de jeux
 · Scène démo
 · Divers
 · Informatique générale


Jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Soutien

N'hésitez pas à soutenir le projet Obligement



Contact

David Brunet

Courriel

 


Programmation : C - les structures de contrôle
(Article écrit par Batchman et extrait d'A-News (Amiga News) - mars 1990)


Maintenant que nous maîtrisons les variables (déclaration, types et classes de stockage), nous allons commencer à mettre quelques instructions autour, histoire d'égayer un peu le paysage.

Ceux qui connaissent Pascal ou Ada ne seront pas dépaysés mais les basico-dépendants vont tomber de haut. Le C est un langage structuré. Il est toujours possible de programmer salement mais, pour bénéficier de la puissance de ce langage, il est nécessaire de respecter quelques règles simples.

Programmez structuré

Vous allez le voir, le langage C est relativement pauvre en instructions : il y a peu de mots-clefs. Les structures de contrôle sont :
  • Le test.
  • L'aiguillage.
  • Les boucles finies ou conditionnelles.
Le test

C'est le classique "si .. alors .. sinon", qui prend ici la syntaxe suivante :

if (condition) instruction ; else instruction ;

Si la condition est vérifiée, la première instruction est exécutée. Dans le cas contraire, c'est la deuxième.

Notez bien ces points :
  • La condition est entre parenthèses. Elle est le résultat d'un test.
  • Il n'y a pas de "alors" (ou "then").
  • "instruction" représente une instruction ou bien un bloc, c'est-à-dire des instructions encadrées par des accolades {} (les "begin" et "end" du Pascal).
  • La partie "else" est facultative. Si elle est absente et si la condition est fausse, le programme passe directement à la suite.
Quelques exemples :

if (a == b) printf("a et b sont égaux\n");
else printf("a et b sont différents\n");

if (a != b) printf("a et b sont différents\n");

if (a != b) {
 printf("a et b sont différents\n");
 a = b;
 printf("maintenant, a et b sont égaux\n");
}

Nous reviendrons dans le prochain article sur les opérateurs, mais vous pouvez déjà noter que "==" représente le test d'égalité et "!=" le test d'inégalité.

Notez également que dans le dernier exemple, trois instructions doivent être exécutées dans le cas où la condition est vérifiée : elles doivent être obligatoirement placées entre accolades.

L'aiguillage

Dans le cas où vous voudriez tester les différentes valeurs que peut prendre une variable, vous avez la possibilité d'écrire une cascade de if :

if (a == 1) ...;
else if (a == 2) ...;
else if (a == 3) ...;
else ...;

Il existe une écriture plus simple, et plus efficace, du point de vue du code généré :

switch (a) {
  case 1: instruction1;
  case 2: instruction2;
  case 3: instruction3;
default: instruction_par_defaut;
}

Si la variable "a" vaut "1", la première ligne est exécutée, si elle vaut "2", la deuxième est exécutée, si elle vaut "3", la troisième est exécutée... Si elle ne correspond à aucune des valeurs, c'est l'option default qui est choisie. Cette clause est facultative.

Mais ce n'est pas si simple, les concepteurs du C ont cru bon de poser ici une mine. En effet, l'instruction exécutée est celle qui correspond à l'alternative choisie mais elle n'est pas la seule : les instructions des cas suivants sont aussi exécutées ! Sauf si vous le demandez explicitement avec un "break" : dans ce cas, le programme saute directement après l'aiguillage.

En clair, si a vaut "2" par exemple, l'instruction2 est exécutée, mais aussi l'instruction3 et l'instruction par défaut. Pour éviter ce problème, il faut écrire :

switch (a) {
 case 1: instruction1;
  break;
 case 2: instruction2;
  break;
 case 3: instruction3;
  break;
 default: instruction_par_defaut;
}

Dans ce cas, si a vaut "2", seule l'instruction2 est exécutée. Ça correspond à un usage plus courant et il est gênant de devoir mettre ces "break". Mais n'épiloguons pas sur ce choix contestable.

Les boucles

Il faut distinguer trois types de boucles :
  • while.
  • do .. while.
  • for.
while (condition) instruction;

L'opération ou le bloc représenté par instruction est exécuté tant que la condition est vraie. Le test est effectué avant l'instruction, donc, si la condition est fausse des le départ, l'instruction n'est pas exécutée.

Exemples :

while (a != b) a = a + 1;

while (a != b) {
 a = a + 1;
 b = b - 1;
}

La boucle "répéter" :

do instruction while (condition);

Ici aussi, l'instruction est exécutée tant que la condition est vraie. Mais le test est effectué après l'instruction, ce qui signifie que l'on rentre au moins une fois dans la boucle, même si la condition est fausse dès le début.

Vous pouvez donc écrire :

do a = a + 1 while (a != b);

do {
 a = a + 1;
 b = b + 1;
} while (a != b);

La boucle "pour" (for) est radicalement différente : le nombre d'itérations est ici en principe fixe. La syntaxe est la suivante :

for (instruction1; condition; instruction2) instruction3;

La boucle "for" est généralement indexée sur un indice. Le rôle de l'instruction1 est d'initialiser cet indice, la condition le teste et l'instruction2 est exécutée à chaque itération, c'est-à-dire, à chaque tour de boucle.

L'instruction3 représente l'instruction ou le bloc répété. Pourquoi ne pas regrouper cette opération avec l'instruction2 ? Ça serait possible mais on réserve généralement l'instruction2 à l'incrémentation de l'indice de boucle.

Cette séquence est rigoureusement équivalente à :

instruction1;
while (condition) {
 instruction2;
 instruction3;
}

Exemples :

for (i=0; i<=100; i=i+1) a[i] = a[i] + 1;

for (i=0; i<=100; i=i+1) {
 a[i] = a[i] + 1;
 b[i] = b[i] + 1;
}

Il faut préciser que chacune des trois expressions figurant entre parenthèses est facultative. Exemple classique, la boucle infinie peut s'écrire :

for (;;) {...}

Autre possibilité intéressante à noter, instruction1 et instruction2 peuvent être des listes d'instructions, séparées par des virgules. Ceci est utile dans les cas où l'initialisation et/ou l'incrémentation ne se fait pas en une seule opération. Par exemple, on peut avoir :

for (i=0,j=1; j =10; i=i+1,j=j+1) a[i,j]=a[i,j]+1;

Les instructions d'échappement

Ces instructions permettent de sortir d'une fonction, d'un bloc ou du programme, en bref, d'interrompre une séquence.

Nous avons déjà vu "break", qui permet de sortir des "switch". Cette instruction autorise aussi la sortie des boucles, par exemple, pour traiter un cas particulier.

Exemple :

for (i=0; i<=100; i=i+1) {
 if (b == 5) break;
 a[i] = a[i] + 1;
 appel_d_une_fonction(&b);
}

Dans cet exemple, il y a un cas particulier si la variable "b" vaut "5". Il faut alors sortir de la boucle. C'est ce que permet le "break".

Autre possibilité, plutôt que de sortir de la boucle, vous pouvez vouloir ne rien faire et passer directement à l'itération suivante. Bien que je trouve que vous ayez des goûts bizarres, voici la solution : c'est l'instruction continue. En clair, continue revient directement au début de la boucle, sans exécuter les instructions qui suivent dans le corps de la boucle, ni passer par la case départ.

Exemple :

for (i=0; i<=100; i=i+1) {
 if (b == 5) continue;
 a[i] = a[i] + 1;
 appel_d_une_fonction(&b);
}

Dans un autre style de réjouissances, "return()" permet de sortir d'une fonction, en fixant sa valeur de retour. Tout de suite, un exemple bête mais qui illustre bien les possibilités de cette instruction :

int valeur_absolue(x)
int x; {
 if (x >= 0) return(x);
 else return(-x);
}

Dès que le "return" est exécuté, le programme revient à la fonction appelante. S'il reste des instructions dans cette fonction, elles sont ignorées. Bien sûr, le type de la variable retournée doit être le même que celui de la fonction (ici int). Par exemple, pour une fonction de type "void", il faut écrire "return();".

"exit()" est l'instruction qui permet de sortir d'un programme. Si le programme retourne une valeur (comme souvent en Unix), vous pouvez la spécifier, de la même façon que dans le cas des fonctions avec "return()". En général, la valeur retournée est "0" dans le cas d'une fin normale, et "-1" en cas d'interruption précipitée des réjouissances. Mais vous pouvez très bien adopter un code différent pour chaque erreur, afin de renseigner le programme appelant (le Shell, par exemple) sur la cause de l'erreur.

Exemples :

exit();

if (b == 0) then exit(-1);
else c = a/b;

Enfin, je mentionne le "goto" pour mémoire. Mais, faites-moi plaisir, ne l'utilisez pas. Les matheux ont montré qu'il était possible d'écrire n'importe quel programme dans un langage évolué comme le C, sans utiliser de "goto". La seule incartade que je tolérerai dans mon infinie bonté, sera l'usage en cas de panique. En effet, on peut admettre, dans le cas où se produit une erreur grave, de sauter en catastrophe à un traitement qui termine l'exécution. En tout cas, pas de "goto" dans tous les sens à l'intérieur d'un programme, pour passer d'un bloc à l'autre. Sinon, je vous raie de la liste de mes lecteurs.

La syntaxe du "goto" :

goto label;
...
label;
...

Voilà, c'est tout pour les structures de contrôle du C. Comme vous le constatez, il y a relativement peu de choses mais elles sont essentielles. Le mois prochain, nous parlerons opérateurs.


[Retour en haut] / [Retour aux articles]