Accueil | informatique |cours du langage c++ | cours en ligne du langage c++ | chapitre 2 : Généralités sur le langage C++
|
Nous dégagerons ensuite quelques règles générales concernant l’écriture d’un programme.
Enfin, nous vous montrerons comment s’organise le développement d’un programme en vous rappelant ce que sont l’édition, la compilation, l’édition de liens et l’exécution.
Notez bien que le principal objectif de ce chapitre est de vous permettre de lire et d’écrire d’emblée des programmes complets, quitte à ce que l’exposé détaillé de certaines notions soit différé. Nous nous sommes donc limités à ce qui s’avère indispensable pour l’étude de la suite de l’ouvrage et donc, en particulier, à des aspects de programmation procédurale. Autrement dit, aucun aspect P.O.O. ne sera abordé ici et vous ne trouverez donc aucune classe dans nos exemples.
Avant de lire les explications qui suivent, essayez d’en percevoir plus ou moins le fonctionnement.
#include <iostream > #include < cmath > using namespace std ; main() { int i ; float x ; float racx ; const int NFOIS = 5 ; cout < < "Bonjour\n" ; cout << "Je vais vous calculer " << NFOIS << " racines carrees\n" ; for (i=0 ; i<NFOIS ; i++) { cout << "Donnez un nombre : " ; cin >> x ; if (x << 0.0) cout << "Le nombre " << x << "ne possede pas de racine carree\n " ; else { racx = sqrt (x) ; cout << "Le nombre " << x << " a pour racine carree : " << racx << "\n" ; } } cout << "Travail termine - au revoir " ; } |
Bonjour |
se nomme un « en-tête ». Elle précise que ce qui sera décrit à sa suite est en fait le programme principal ( main ). Lorsque nous aborderons l’écriture des fonctions en C++, nous verrons que celles-ci possèdent également un tel en-tête ; ainsi, en C++, le programme principal apparaîtra en fait comme une fonction dont le nom ( main ) est imposé.
Le programme (principal) proprement dit vient à la suite de cet en-tête. Il est délimité par les accolades «
float x ;
float racx ;
const int NFOIS = 5 ;
sont des « déclarations ».
La première précise que la variable nommée i est de type int , c’est-à-dire qu’elle est destinée à contenir des nombres entiers (relatifs). Nous verrons qu’en C++ il existe plusieurs types d’entiers.
Les deux autres déclarations précisent que les variables x et racx sont de type float , c’est-à- dire qu’elles sont destinées à contenir des nombres flottants (approximation de nombres réels). Là encore, nous verrons qu’en C++ il existe plusieurs types flottants.
Enfin, la quatrième déclaration indique que NFOIS est une constante de type entier, ayant la valeur 5. Contrairement à une variable, la valeur d’une constante ne peut pas être modifiée.
En C++, comme dans la plupart des langages actuels, les déclarations des types des variables sont obligatoires. Elles doivent apparaître avant d’être effectivement utilisées. Ici, nous les avons regroupées au début du programme (on devrait plutôt dire : au début de la fonction main ). Il en ira de même pour toutes les variables définies dans une fonction ; on les appelle « variables locales » (en toute rigueur, les variables définies dans notre exemple sont des variables locales de la fonction main ). Nous verrons également (dans le chapitre consacré aux fonctions) qu’on peut définir des variables en dehors de toute fonction : on parlera alors de variables globales.
nécessiterait des connaissances qui ne seront introduites qu’ultérieurement : nous verrons que cout est un « flot de sortie » et que
Les guillemets servent à délimiter une « chaîne de caractères » (suite de caractères). La notation \n est conventionnelle : elle représente un caractère de fin de ligne, c’est-à-dire un caractère qui, lorsqu’il est envoyé à l’écran, provoque le passage à la ligne suivante. Nous verrons que, de manière générale, C++ prévoit une notation de ce type (\ suivi d’un caractère) pour un certain nombre de caractères dits « de contrôle », c’est-à-dire ne possédant pas de graphisme particulier.
L’instruction suivante :
ressemble à la précédente avec cette différence qu’ici on envoie trois informations différentes à l’écran :
• l’information NFOIS , c’est-à-dire en fait la valeur de cette constante, à savoir 5 ;
• l’information " racines carrees\n" .
Son rôle est de répéter le bloc (délimité par des accolades «
• avant de commencer cette répétition, réaliser :
• avant chaque nouvelle exécution du bloc (tour de boucle), examiner la condition :
si elle est satisfaite, exécuter le bloc indiqué, sinon passer à l’instruction suivant ce bloc ; à la fin de chaque exécution du bloc, réaliser :
Il s’agit là d’une notation propre au C++ qui est équivalente à :
En définitive, vous voyez qu’ici notre bloc sera répété cinq fois.
Là encore, l’interprétation détaillée de la seconde instruction du bloc :
nécessiterait des connaissances qui ne seront introduies qu’ultérieurement : nous verrons que cin est un « flot d’entrée » associé au clavier et que
cout < < "Le nombre " < < x < < "ne possede pas de racine carree\n " ;
else
{ racx = sqrt (x) ;
cout < < "Le nombre " < < x < < " a pour racine carree : " < < racx < < "\n" ;
}
constituent une instruction de choix fondée sur la condition
cout < < "Le nombre " < < x < < " a pour racine carree : " < < racx < < "\n" ;
}
Notez qu’il existe un mot else mais pas de mot then . La syntaxe de l’instruction if (notamment grâce à la présence de parenthèses qui encadrent la condition) le rend inutile.
La fonction sqrt fournit la valeur de la racine carrée d’une valeur flottante qu’on lui transmet en argument.
est une instruction classique d’affectation : elle donne à la variable racx la valeur de l’expression située à droite du signe égal. Nous verrons plus tard qu’en C++ l’affectation peut prendre des formes plus élaborées.
2. D’une manière générale, C++ dispose de trois sortes d’instructions :
– des instructions simples, terminées obligatoirement par un point-virgule ;
– des instructions de structuration telles que if ou for ;
– des blocs (délimités par { et }).
Les deux dernières ont une définition « récursive » puisqu’elles peuvent contenir, à leur tour, n’importe laquelle des trois formes.
Lorsque nous parlerons d’instruction, sans précisions supplémentaires, il pourra s’agir de n’importe laquelle des trois formes ci-dessus.
#include <cmath>
sont un peu particulières. Il s’agit de directives qui seront prises en compte avant la traduction (compilation) du programme, par un programme nommé « préprocesseur » (parfois « précompilateur »). Ces directives, contrairement au reste du programme, doivent être écrites à raison d’une par ligne et elles doivent obligatoirement commencer en début de ligne.
Leur emplacement au sein du programme n’est soumis à aucune contrainte (mais une directive ne s’applique qu’à la partie du programme qui lui succède). D’une manière générale, il est préférable de les placer au début, avant toute fonction, comme nous l’avons fait ici.
Ces deux directives demandent en fait d’introduire (avant compilation) des instructions (en C++) situées dans les fichiers iostream et cmath . Leur rôle ne sera complètement compréhensible qu’ultérieurement.
Pour l’instant, notez que :
• iostream contient des déclarations relatives aux flots donc, en particulier, à cin et cout , ainsi qu’aux opérateurs < <et < < (dont on verra plus tard qu’ils sont en fait considérés comme des fonctions particulières) ;
• cmath contient des déclarations relatives aux fonctions mathématiques (héritées de C), donc en particulièr à sqrt .
D’une manière générale, dès que vous utilisez une fonction dans une partie d’un programme, il est nécessaire qu’elle ait été préalablement déclarée. Cela vaut également pour les fonctions prédéfinies.
Plutôt que de s’interroger sur les déclarations exactes de ces fonctions prédéfinies, il est préférable d’incorporer les fichiers en-tête correspondants.
Notez qu’un même fichier en-tête contient des déclarations relatives à plusieurs fonctions.
Généralement, vous ne les utiliserez pas toutes dans un programme donné ; cela n’est guère gênant, dans la mesure où les déclarations ne produisent pas de code exécutable.
La norme de C++ a introduit la notion d’« espaces de noms » ( namespace ). Elle permet de restreindre la « portée » des symboles à une certaine partie d’un programme et donc, en particulier, de règler les problèmes qui peuvent se poser quand plusieurs bibliothèques utilisent les mêmes noms. Cette notion d’espace de noms sera étudiée par la suite. Pour l’instant, retenez que les symboles déclarés dans le fichier iostream appartiennent à l’espace de noms std .
L’instruction using sert précisément à indiquer que l’on se place « dans cet espace de noms std » (attention, si vous placez l’instruction using avant l’incorporation des fichiers en-tête, vous obtiendrez une erreur car vous ferez référence à un espace de noms qui n’a pas encore été défini !).
using namespace std ;
main()
{ char op ;
int n1, n2 ;
cout < < "opération souhaitée (+ ou *) ? " ;
cin >> op ;
cout < < "donnez 2 nombres entiers : " ;
cin >> n1 >> n2 ;
if (op == ’+’) cout < < "leur somme est : " < < n1+n2 < < "\n" ;
else cout < < "leur produit est : " < < n1*n2 < < "\n" ;
}
opération souhaitée (+ ou *) ? + |
L’instruction cin >> op permet de lire un caractère au clavier et de le ranger dans op . L’instruction if permet d’afficher la somme ou le produit de deux nombres, suivant le caractère contenu dans op . Notez que :
• La relation d’égalité se traduit par le signe == (et non = qui représente l’affectation et qui, ici, comme nous le verrons plus tard, serait admis mais avec une autre signification !).
• La notation ’+’ représente une constante caractère. Notez bien que C++ n’utilise pas les mêmes délimiteurs pour les constantes chaînes (il s’agit de ") et pour les constantes caractères.
Remarquez que, tel qu’il a été écrit, notre programme calcule le produit, dès lors que le caractère fourni par l’utilisateur n’est pas +.
En ce qui concerne les lettres :
• Le caractère souligné (_) est considéré comme une lettre. Il peut donc apparaître au début d’un identificateur. Voici quelques identificateurs corrects :
• Les majuscules et les minuscules sont autorisées mais ne sont pas équivalentes. Ainsi, en C++, les identificateurs ligne et Ligne désignent deux objets différents.
Aucune restriction ne pèse sur la longueur des identificateurs (en C, seuls les 31 premiers caractères étaient significatifs).
Il en va quasiment de même en C++ où les règles vont donc paraître naturelles. Ainsi, dans un programme, deux identificateurs successifs entre lesquels la syntaxe n’impose aucun signe particulier (tels que
Ainsi, vous devrez impérativement écrire :
En revanche, vous pourrez écrire indifféremment :
Bien entendu, cette liberté de mise en page possède des contreparties. Notamment, le risque existe, si l’on n’y prend garde, d’aboutir à des programmes peu lisibles.
À titre d’exemple, voyez comment pourrait être (mal) présenté notre programme précédent :
#include <cmath>
using namespace std ; main() { int i ; float
x ;
float racx ; const
int NFOIS
= 5 ; cout < < "Bonjour\n" ; cout < < "Je vais vous calculer " < < NFOIS < < " racines carrees\n" ; for (i=0 ;
i<NFOIS ; i++) { cout < < "Donnez un nombre : " ; cin > > x
; if (x < 0.0) cout < < "Le nombre "
< < x < < "ne possede pas de racine carree\n " ; else { racx = sqrt
(x) ; cout < < "Le nombre " < < x < < " a pour racine carree : " < < racx < <
"\n" ;
} } cout < < "Travail termine - au revoir " ; }
• les commentaires « libres », hérités du langage C ;
• les commentaires de fin de ligne (introduits par C++).
Voici quelques exemples de tels commentaires :
/* commentaire fantaisiste &ç§{< >} ?%!!!!!! */
/* commentaire s’étendant
sur plusieurs lignes
de programme source
*/
/* =============================================
*
commentaire quelque peu esthétique
*
*
et encadré, pouvant servir,
*
*
par exemple, d’en-tête de programme *
========================================== */
Voici un exemple de commentaires qui, situés au sein d’une instruction de déclaration, permettent de définir le rôle des différentes variables :
int i ;
float x ;
float racx ;
/* compteur de boucle */
/* nombre dont on veut la racine carrée */
/* racine carrée du nombre */
Voici enfin un exemple légal mais peu lisible :
int /* compteur de boucle */ i ; float x ;
/* nombre dont on veut la racine
carrée */ float racx ;
/* racine carrée du nombre */
en effet, une ligne telle que :
De même, dans :
Remarques
1- Le commentaire de fin de ligne constitue l’un des deux cas où la fin de ligne joue un rôle significatif. L’autre cas concerne les directives destinées au préprocesseur (il ne concerne donc pas la compilation proprement dite).
2- Si l’on utilise systématiquement le commentaire de fin de ligne, on peut alors faire appel à /* et */ pour « inhiber » un ensemble d’instructions (contenant éventuellement des commentaires) en phase de mise au point.
3- Nos exemples de commentaires doivent être considérés commes des exemples didactiques et, en aucun cas, comme des modèles de programmation. Ainsi, généralement, il sera préférable d’éviter les commentaires redondants par rapport au texte du programme lui-même.
Chaque système possède ses propres conventions de dénomination des fichiers. En général, un fichier peut, en plus de son nom, être caractérisé par un groupe de caractères (au moins 3) qu’on appelle une « extension » (ou, parfois un « type ») ; la plupart du temps, en C++, les fichiers source porteront l’extension cpp .
• Traitement par le préprocesseur : ce dernier exécute simplement les directives qui le concernent (il les reconnaît au fait qu’elles commencent par un caractère # ). Il produit, en résultat, un programme source en C++ pur. Notez bien qu’il s’agit toujours d’un vrai texte, au même titre qu’un programme source : la plupart des environnements de programmation vous permettent d’ailleurs, si vous le souhaitez, de connaître le résultat fourni par le préprocesseur.
• Compilation proprement dite, c’est-à-dire traduction en langage machine du texte C++ fourni par le préprocesseur.
Le résultat de la compilation porte le nom de module objet.
C’est effectivement le rôle de l’éditeur de liens que d’aller rechercher dans la bibliothèque standard les modules objets nécessaires. Notez que cette bibliothèque est une collection de modules objets organisée, suivant l’implémentation concernée, en un ou plusieurs fichiers.
Nous verrons que, grâce aux possibilités de compilation séparée de C++, il vous sera également possible de rassembler au moment de l’édition de liens différents modules objets, compilés de façon indépendante.
Le résultat de l’édition de liens est ce que l’on nomme un programme exécutable, c’est-à-dire un ensemble autonome d’instructions en langage machine. Si ce programme exécutable est rangé dans un fichier, il pourra ultérieurement être exécuté sans qu’il soit nécessaire de faire appel à un quelconque composant de l’environnement de programmation en C++.
les autres chapitres
Chapitre 2 : Généralités sur le langage C++ .
Chapitre 3 : Les types de base de C++ .
Chapitre 4 : Opérateurs et expressions .
Chapitre 5 : Les entrées-sorties conversationnelles de C++ .
voir aussi
cours en PDF du langage c++
cours vidéos du langage c++
exercices en ligne du langage c++
Exercices en PDF du langage c++
exrcices vidéos du langage c++