Cours de C/C++ Modularité des programmes et génération des binaires

Cours de C/C++ Modularité des programmes et génération des binaires, tutoriel & guide de travaux pratiques langage C en pdf.

Les structures de contrôle

Nous allons aborder dans ce chapitre un autre aspect du langage indispensable à la programmation, à savoir : les structures de contrôle. Ces structures permettent, comme leur nom l’indique, de contrôler l’exécution du programme en fonction de critères particuliers. Le C et le C++ disposent de toutes les structures de contrôle classiques des langages de programmation comme les tests, les boucles, les sauts, etc. Toutes ces structures sont décrites dans les sections suivantes.
Les tests
Les tests sont les structures qui permettent de sélectionner une instruction ou un groupe d’instructions en fonction du résultat d’un test.
La structure conditionnelle if
La structure conditionnelle if permet de réaliser un test et d’exécuter une instruction ou non selon le résultat de ce test. Sa syntaxe est la suivante :
if (test) opération;
où test est une expression dont la valeur est booléenne ou entière. Toute valeur non nulle est consi-dérée comme vraie. Si le test est vrai, opération est exécuté. Ce peut être une instruction ou un bloc d’instructions. Une variante permet de spécifier l’action à exécuter en cas de test faux :
if (test) opération1;
else opération2;
Note : Attention ! Les parenthèses autour du test sont nécessaires !
Les opérateurs de comparaison sont les suivants :
Il n’y a pas d’opérateur ou logique exclusif.
Exemple 2-1. Test conditionnel if
if (a<b && a!=0)
{
m=a;
nouveau_m=1;
}
Le branchement conditionnel
Dans le cas où plusieurs instructions différentes doivent être exécutées selon la valeur d’une variable de type intégral, l’écriture de if successifs peut être relativement lourde. Le C/C++ fournit donc la structure de contrôle switch, qui permet de réaliser un branchement conditionnel. Sa syntaxe est la suivante :
switch (valeur)
{
case cas1:
[instruction;
[break;]
]
case cas2:
[instruction;
[break;]
]
case casN:
[instruction;
[break;]
]
[default:
[instruction;
[break;]
]
]
}
valeur est évalué en premier. Son type doit être entier. Selon le résultat de l’évaluation, l’exécution du programme se poursuit au cas de même valeur. Si aucun des cas ne correspond et si default est présent, l’exécution se poursuit après default. Si en revanche default n’est pas présent, on sort du switch.
Les instructions qui suivent le case approprié ou default sont exécutées. Puis, les instructions du cas suivant sont également exécutées (on ne sort donc pas du switch). Pour forcer la sortie du switch, on doit utiliser le mot clé break.
Exemple 2-2. Branchement conditionnel switch
i= 2;
switch (i)
{
case 1:
case 2: /* Si i=1 ou 2, la ligne suivante sera exécutée. */ i=2-i;
break;
case 3:
i=0; /* Cette ligne ne sera jamais exécutée. */ default:
break;
}
Note : Il est interdit de définir une variable dans un des case d’un switch.
Les boucles
Les boucles sont des structures de contrôle qui permettent de réaliser une opération plusieurs fois, tant qu’une condition est vérifiée.
 La boucle for
La structure de contrôle for est sans doute l’une des boucles les plus importantes. Elle permet de réaliser toutes sortes de boucles et, en particulier, les boucles permettant d’itérer sur un ensemble de valeur d’une variable de contrôle. Sa syntaxe est la suivante :
for (initialisation ; test ; itération) opération;
où initialisation est une instruction évaluée avant le premier parcours de la boucle du for. test est une expression dont la valeur déterminera la fin de la boucle. itération est une instruction effectuée à la fin de chaque passage dans la boucle, et opération constitue le traitement de la boucle elle-même. Chacune de ces parties est facultative.
La séquence d’exécution est la suivante :
initialisation
test
si vrai :
opération
itération
retour au test
fin du for.
Exemple 2-3. Boucle for
somme = 0;
for (i=0; i<=10; i=i+1) somme = somme + i;
Note : En C++, il est possible que la partie initialisation déclare une variable. Dans ce cas, la variable déclarée n’est définie qu’à l’intérieur de l’instruction for. Par exemple,
for (int i=0; i<10; ++i);
est strictement équivalent à :
{
int i;
for (i=0; i<10; ++i);
}
Cela signifie que l’on ne peut pas utiliser la variable i après l’instruction for, puisqu’elle n’est définie que dans le corps de cette instruction. Cela permet de réaliser des variables muettes qui ne servent qu’à l’instruction for dans laquelle elles sont définies.
Note : Cette règle n’était pas respectée par certains compilateurs jusqu’à encore récemment. En effet, historiquement, les premiers compilateurs autorisaient bien la définition d’une variable dans la partie initialisation des boucles for, mais cette variable n’était pas limitée à l’intérieur de la boucle. Elle restait donc accessible après cette instruction. La différence est subtile, mais importante. Cela pose assurément des problèmes de compatibilité et les programmes C++ rela-tivement anciens écrits pour ces compilateurs doivent être portés, puisque dans un cas la variable doit être redéclarée et dans l’autre cas elle ne le doit pas. Dans ce cas, le plus simple est de ne pas déclarer la variable de contrôle dans la partie initialisation de l’instruction for, mais juste avant, afin de revenir à la sémantique originelle.
 Le while
Le while permet d’exécuter des instructions en boucle tant qu’une condition est vraie. Sa syntaxe est la suivante :
while (test) opération;
où opération est effectuée tant que test est vérifié. Comme pour le if, les parenthèses autour du test sont nécessaires. L’ordre d’exécution est :
test
si vrai :
opération
retour au test
Exemple 2-4. Boucle while
somme = i = 0;
while (somme<1000)
{
somme = somme + 2 * i / (5 + i);
i = i + 1;
}
Le do
La structure de contrôle do permet, tout comme le while, de réaliser des boucles en attente d’une condition. Cependant, contrairement à celui-ci, le do effectue le test sur la condition après l’exécution des instructions. Cela signifie que les instructions sont toujours exécutées au moins une fois, que le test soit vérifié ou non. Sa syntaxe est la suivante :
do opération;
while (test);
opération est effectuée jusqu’à ce que test ne soit plus vérifié.
L’ordre d’exécution est :
opération
test
si vrai, retour à opération
Exemple 2-5. Boucle do
p = i = 1;
do
{
p = p * i;
i = i + 1;
} while (i != 10);

Les instructions de rupture de séquence et de saut

Les instructions de rupture de séquence permettent, comme leur nom l’indique, d’interrompre une séquence d’instructions et de passer à la séquence suivante directement. Elles sont souvent utilisées pour sortir des boucles, pour passer à l’itération suivante, ou pour traiter une erreur qui s’est produite pendant un traitement.
Les instructions de rupture de séquence
Les commandes de rupture de séquence sont les suivantes :
return [valeur];
break;
continue;
return permet de quitter immédiatement la fonction en cours. Comme on l’a déjà vu, la commande return peut prendre en paramètre la valeur de retour de la fonction.
break permet de passer à l’instruction suivant l’instruction while, do, for ou switch la plus im-briquée (c’est-à-dire celle dans laquelle on se trouve).
continue saute directement à la dernière ligne de l’instruction while, do ou for la plus imbriquée. Cette ligne est l’accolade fermante. C’est à ce niveau que les tests de continuation sont faits pour for et do, ou que le saut au début du while est effectué (suivi immédiatement du test). On reste donc dans la structure dans laquelle on se trouvait au moment de l’exécution de continue, contrairement à ce qui se passe avec le break.
Exemple 2-6. Rupture de séquence par continue
/* Calcule la somme des 1000 premiers entiers pairs : */ somme_pairs=0;
for (i=0; i<1000; i=i+1)
{
if (i % 2 == 1) continue;
somme_pairs=somme_pairs + i;
}
Le saut
Le C/C++ dispose également d’une instruction de saut permettant de poursuivre l’exécution du pro-gramme en un autre point. Bien qu’il soit fortement déconseillé de l’utiliser, cette instruction est nécessaire et peut parfois être très utile, notamment dans les traitements d’erreurs. Sa syntaxe est la suivante :
goto étiquette;
où étiquette est une étiquette marquant la ligne destination dans la fonction. Les étiquettes sont simplement déclarées avec la syntaxe suivante :
étiquette:
Les étiquettes peuvent avoir n’importe quel nom d’identificateur.
Il n’est pas possible d’effectuer des sauts en dehors d’une fonction. En revanche, il est possible d’effectuer des sauts en dehors et à l’intérieur des blocs d’instructions sous certaines conditions. Si la destination du saut se trouve après une déclaration, cette déclaration ne doit pas comporter d’initialisations. De plus, ce doit être la déclaration d’un type simple (c’est-à-dire une déclaration qui ne demande pas l’exécution de code) comme les variables, les structures ou les tableaux. Enfin, si, au cours d’un saut, le contrôle d’exécution sort de la portée d’une variable, celle-ci est détruite.
Note : Ces dernières règles sont particulièrement importantes en C++ si la variable est un objet dont la classe a un constructeur ou un destructeur non trivial. Voir le Chapitre 7 pour plus de détails à ce sujet.
Autre règle spécifique au C++ : il est impossible d’effectuer un saut à l’intérieur d’un bloc de code en exécution protégée try {}. Voir aussi le Chapitre 8 concernant les exceptions.

LIRE AUSSI :  Cours langage C visibilité des variables

I. Le langage C++
1. Première approche du C/C++
1.1. Les ordinateurs, les langages et le C++
1.2. Notre premier programme
1.3. Les commentaires en C/C++
1.4. Les variables
1.5. Les instructions
1.6. Les fonctions et les procédures
1.7. Les entrées / sorties en C
2. Les structures de contrôle
2.1. Les tests
2.2. Les boucles
2.3. Les instructions de rupture de séquence et de saut
3. Types avancés et classes de stockage
3.1. Types de données portables
3.2. Structures de données et types complexes
3.3. Les énumérations
3.4. Les alias de types
3.5. Transtypages et promotions
3.6. Les classes de stockage
4. Les pointeurs et références
4.1. Notion d’adresse
4.2. Notion de pointeur
4.3. Déréférencement, indirection
4.4. Notion de référence
4.5. Lien entre les pointeurs et les références
4.6. Passage de paramètres par variable ou par valeur
4.7. Références et pointeurs constants et volatiles
4.8. Arithmétique des pointeurs
4.9. Utilisation des pointeurs avec les tableaux
4.10. Les chaînes de caractères : pointeurs et tableaux à la fois !
4.11. Allocation dynamique de mémoire
4.12. Pointeurs et références de fonctions
4.13. Paramètres de la fonction main – ligne de commande
4.14. DANGER
5. Le préprocesseur C
5.1. Définition
5.2. Les directives du préprocesseur
5.3. Les macros
5.4. Manipulation de chaînes de caractères dans les macros
5.5. Les trigraphes
6. Modularité des programmes et génération des binaires
6.1. Pourquoi faire une programmation modulaire ?
6.2. Les différentes phases du processus de génération des exécutables
6.3. Compilation séparée en C/C++
6.4. Syntaxe des outils de compilation
6.5. Problèmes syntaxiques relatifs à la compilation séparée
7. C++ : la couche objet
7.1. Généralités
7.2. Extension de la notion de type du C
7.3. Déclaration de classes en C++
7.4. Encapsulation des données
7.5. Héritage
7.6. Classes virtuelles
7.7. Fonctions et classes amies
7.8. Constructeurs et destructeurs
7.9. Pointeur this
7.10. Données et fonctions membres statiques
7.11. Surcharge des opérateurs
7.12. Des entrées – sorties simplifiées
7.13. Méthodes virtuelles
7.14. Dérivation
7.15. Méthodes virtuelles pures – Classes abstraites
7.16. Pointeurs sur les membres d’une classe
8. Les exceptions en C++
8.1. Techniques de gestion des erreurs
8.2. Lancement et récupération d’une exception
8.3. Hiérarchie des exceptions
8.4. Traitement des exceptions non captées
8.5. Liste des exceptions autorisées pour une fonction
8.6. Gestion des objets exception
8.7. Exceptions dans les constructeurs et les destructeurs
9. Identification dynamique des types
9.1. Identification dynamique des types
9.2. Transtypages C++
10. Les espaces de nommage
10.1. Définition des espaces de nommage
10.2. Déclaration using
10.3. Directive using
11. Les template
11.1. Généralités
11.2. Déclaration des paramètres template
11.3. Fonctions et classes template
11.4. Instanciation des template
11.5. Spécialisation des template
11.6. Mot-clé typename
11.7. Fonctions exportées
12. Conventions de codage et techniques de base
12.1. Conventions de codage
12.2. Méthodes et techniques classiques
12.3. Considérations système
II. La bibliothèque standard C++
13. Services et notions de base de la bibliothèque standard
13.1. Encapsulation de la bibliothèque C standard
13.2. Définition des exceptions standards
13.3. Abstraction des types de données : les traits
13.4. Abstraction des pointeurs : les itérateurs
13.5. Abstraction des fonctions : les foncteurs
13.6. Gestion personnalisée de la mémoire : les allocateurs
13.7. Notion de complexité algorithmique
14. Les types complémentaires
14.1. Les chaînes de caractères
14.2. Les types utilitaires
14.3. Les types numériques
15. Les flux d’entrée / sortie
15.1. Notions de base et présentation générale
15.2. Les tampons
15.3. Les classes de base des flux : ios_base et basic_ios
15.4. Les flux d’entrée / sortie
15.5. Les flux d’entrée / sortie sur chaînes de caractères
15.6. Les flux d’entrée / sortie sur fichiers
16. Les locales
16.1. Notions de base et principe de fonctionnement des facettes
16.2. Les facettes standards
16.3. Personnalisation des mécanismes de localisation
17. Les conteneurs 
17.1. Fonctionnalités générales des conteneurs
17.2. Les séquences
17.3. Les conteneurs associatifs
18. Les algorithmes 
18.1. Opérations générales de manipulation des données
18.2. Opérations de recherche
18.3. Opérations d’ordonnancement
18.4. Opérations de comparaison
18.5. Opérations ensemblistes
19. Conclusion
BIBLIOGRAPHIE

………..

Cours gratuitTélécharger le cours complet

Télécharger aussi :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *