Remédiation en C++

Généralités sur le C++

Université de Bordeaux – Licence Ingénierie Mathématique

Bienvenue dans ce tutoriel ! Son objectif est de vous faire découvrir les bases de l’écriture d’un programme en C++.

Le tuto se présente sous forme de diapos où je vous montrerai des exemples commentés de code. Mais la programmation ne s’apprend vraiment que lorsqu’on code soi-même. C’est pour cela que je vous invite à préparer votre machine personnelle, pour que vous puissiez vous-même écrire les programmes et faire des tests. J’ai préparé d’autres diapos qui expliquent comment faire.

Votre machine est prête ? Alors commençons !

Dans cette première partie, je vais vous donner quelques infos sur le C++ en général. Ce que c’est, qui l’utilise et pourquoi, comment il est apparu, etc. On va également construire et compiler un premier programme.

Au cours de la présentation, je poserai des questions sous forme de QCM. Essayez de jouer le jeu et d’y répondre pour vérifier que vous avez bien compris au fur et à mesure !

Commençons par nous intéresser à ce qu’on va produire dans un cours de programmation, c’est-à-dire, aux programmes.

Qu’est ce qu’un programme ?

l'agent Smith est un programme, donc une suite de 0 et de 1 Un programme, c’est une suite d’instructions que l’ordinateur va exécuter.

Ces instructions sont écrites en binaire, c’est à dire une suite de 0 et de 1, totalement illisibles par un être humain. Elles sont parfois placées dans un fichier qu’on appelle exécutable ou simplement binaire. Sous Windows, ce sont les fichiers qui se terminent par ".exe". Sous Linux ou Mac, les exécutables n’ont en général pas d’extension.

En plus, les instructions que contiennent les binaires sont très limitées: addition, multiplication, lire dans une case mémoire, écrire dans une case mémoire, etc. C’est très loin du niveau d’abstraction qu’on a quand on fait des maths !

Les langages informatiques

Les programmes sont donc illisibles et compliqués. Il faut pourtant que quelqu’un les écrive !

Pour cela, il existe beaucoup de langages de programmation. Ils ont chacun leurs particularités, mais ils permettent tous de générer les opérations que va faire la machine à partir d’instructions lisibles et plus abstraites que les opérations machine. Ces instructions sont placées dans des fichiers qu’on appelle fichiers sources.

schema de la conversion des fichiers sources vers une suite de 0 et de 1

Les langages informatiques

Parmi les propriétés qui différencient les langages entre eux, il y a la façon dont est transformée l’écriture lisible en instructions binaires. Pour certains langages, la transformation se fait à la volée, au moment de la lecture des fichiers sources. Il n’y a pas de fichier exécutable à ouvrir dans ce cas.

Ces langages sont dits interprétés. On y trouve par exemple Python, Ruby, Perl, Lisp, etc.

Ces langages sont assez faciles d’accès, et permettent d’être flexible dans son travail. Mais l’interprétation (la conversion en binaire) doit être faite à chaque exécution du programme. C’est une opération qui est assez souvent coûteuse en temps de calcul. Ça veut donc dire que les programmes sont généralement lents.

La compilation

Imaginons maintenant que notre programme ne va plus beaucoup changer. On sait quelles opérations vont être réalisées. On a alors tout intérêt à effectuer la conversion des instructions lisibles en instructions binaires avant de faire tourner le programme. On met alors le résultat dans un fichier (l’éxécutable), et il n’y a plus qu’à ouvrir ce fichier pour lancer le programme.

Dans ce cas, on appelle cette conversion des intructions la compilation, et le «traducteur» qui effectue l’opération un compilateur.

Parmi les langages compilés, on trouve C, C++, C#, Fortran, Java…

Comme ce tuto est un tuto de C++, on devra donc voir comment utiliser un compilateur.

Mais avant cela, continuons les présentations avec C++.

Le langage C++

logo C++ portrait de Bjarne Stroustrup Un peu d’histoire. En 1978, l’invention du langage C a constitué une révolution dans le domaine de l’informatique car il a permis de faciliter la programmation en se détachant du langage machine.

Vers 1983, Bjarne Stroustrup poursuit cet effort d’abstraction en créant C++, qu’il appelait à l’origine «C with Classes».

Le C++ est un langage qui permet un usage plus général, avec des niveaux d’abstraction très proches de ce qu’on utilise habituellement. Mais comme C++ englobe le langage C (il a été construit autour), on peut rester proche des instructions machine, ce qui crée des programmes qui sont performants.

Aujourd’hui C++ est utilisé pour écrire un très grand nombre de programmes, par exemple:

  • les systèmes d’exploitation MS Windows, la suite MS Office,
  • Chrome, Firefox,
  • Photoshop, Spotify, Youtube, et plein d’autres encore.

Le langage C++

C++ est donc très utilisé. Cela a un avantage conséquent : il y a une très grande communauté de développeurs qui se sont forcément posé les mêmes questions que vous.

N’hésitez pas à chercher sur le web quand vous avez une question précise.

Attention cependant à ne pas recopier des solutions toutes faites que vous ne comprenez pas. Vous risquez de commettre des erreurs, et de compliquer inutilement votre programme. En plus, ça se voit comme le nez au milieu de la figure.

 

 

Aussi, C++ est un langage «vivant» car il continue à évoluer. La première standardisation du C++, qui fixe les règles du langage, date de 1998 (15 ans après sa création !). Mais d’autres standards ont suivi: C++11, C++14, C++20. Ils apportent chacun leurs lots de nouveautés.

La compilation (suite)

Revenons à la compilation. Dans ce tuto, on va expliquer comment compiler un simple fichier source pour générer un petit programme.

L’écrasante majorité des programmes écrits en C++ comportent plus d’un fichier. La compilation de plusieurs fichiers sera vue en cours. On verra aussi comment automatiser la compilation.

Pour compiler, il faut un compilateur. Normal. Il en existe un bon nombre:

  • gcc du consortium GNU (pour Windows, Linux, Mac)
  • Les compilateurs Intel (pour Windows, Linux, Mac)
  • MS Visual C++ (pour Windows)
  • etc

Dans ce tutoriel, on utilisera gcc pour compiler, ou plutot sa variante dédiée au C++ appelée g++. N’oubliez pas de l’installer sur votre machine si ce n’est pas déjà fait. Pour savoir comment faire, c’est par ici.

La compilation (suite)

Commençons par écrire un petit programme. Ouvrez un éditeur de texte, et dans un nouveau fichier copiez les lignes suivantes:

capture d'écran saisie hello.cpp

#include <iostream>

int main()
{
  std::cout << "Bonjour, j'ai ete ecrit en C++" << std::endl;
  return 0; 
}

Enregistrez le fichier sous le nom hello.cpp (placez le dans un dossier de travail qui servira à ce tuto).

On ajoute aux fichiers sources C++ l’extension ".cpp", même si ce n’est pas obligatoire. C’est une convention qu’il vaut mieux suivre, parce que les systèmes d’exploitation et la plupart des éditeurs utilisent l’extension pour déterminer le type de fichier. Par exemple, pour colorer les mots clés quand on écrit le code.

On trouve aussi parfois aussi les extensions ".c++", ".cxx" ou ".cc" qui sont toutes connues comme associées au C++, mais sont plus rarement utilisées.

La compilation (suite)

Compilons maintenant ce programme.

Dans un terminal, placez vous dans votre dossier de travail. Entrez ensuite la commande suivante:

g++ -c hello.cpp

Normalement, il n’y a aucun affichage à l’écran. C’est le signe que tout s’est bien passé.

En faisant ls, vous devriez voir qu’un fichier hello.o a été créé.

La compilation : fichiers objet, édition de liens

Nous venons de créer ce qu’on appelle un fichier objet. Ce type de fichier contient des instructions en binaire (essayez de l’ouvrir avec votre éditeur de texte!). Mais ce n’est pas encore l’exécutable final.

Même dans ce très court programme, on a invoqué des éléments qui se trouvent dans la bibliothèque iostream: std::cout, std::endl, et les opérateurs << en lien avec ceux-ci.

Une bibliothèque est un ensemble de fichiers qui contient des variables et des fonctions qui permettent de réaliser des opérations autour du même thème. La bibliothèque iostream (pour «input/output stream») permet de gérer tous les flux d’entrée et sortie standard: le clavier, l’écran, etc. L’installation du compilateur vient avec un grand nombre de bibliothèques dites standard qui permettent de réaliser les opérations de base.

La compilation : fichiers objet, édition de liens

Il faut donc maintenant que le compilateur aille chercher des instructions binaires dans des fichiers objets de la bibliothèque iostream. Cette deuxième étape de regroupement de tous les fichiers objets s’appelle l’édition de liens.

Dans le terminal, entrez

g++ hello.o -o hello

Vous devriez avoir dans votre dossier un fichier nommé hello, sans extension. C’est le nom que j’ai donné après l’option -o de g++. Il aurait pu être totalement différent. Mon terminal colore ce fichier en vert pour me signaler que c’est un exécutable.

Sous Windows, il n’y a pas le choix. Les fichiers exécutables doivent avoir l’extension ".exe".

L’édition de liens est «sous-traitée» par gcc à un programme appelé ld. Si vous voyez un message d’erreur commençant par ld avec undefined reference, c’est en général pour vous signaler qu’un fichier objet n’est pas trouvé, ou que certains éléments de ces fichiers sont manquants.

La compilation : fichiers objet, édition de liens

Pour de petits programmes tels que hello.cpp, le compilateur peut réaliser toutes les opérations de compilation et d’éditons de liens en une fois. On peut directement entrer dans le terminal

g++ hello.cpp -o hello

Et le fichier exécutable hello sera créé. Ceci dit, c’est important de savoir quelles sont les étapes de la compilation pour comprendre les messages d’erreur que vous donnera le compilateur.

La compilation : quelques options courantes.

Avant de tester le programme, je vais vous présenter quelques unes des options qu’on peut ajouter à la commande de compilation de g++. Les options que je vais lister ne sont pas exclusives, vous pouvez les cumuler.

Avertissements

g++ hello.cpp -c -Wall
g++ hello.o -o hello

L’option -Wall active les avertissements («Warnings all»). En plus de lister les erreurs d’écriture qui empêchent la compilation, g++ peut détecter des comportements qui peuvent produire des bugs. Il est fortement recommandé d’avoir un code qui ne produit aucun avertissement à la compilation. Certains projets exigent cela !

Inclure un standard

Je vous ai dit que le langage C++ évolue avec le temps, et que les standards rajoutent des nouveautés à chaque sortie. Parfois, et surtout pour les standards récents, il faut préciser au compilateur que le code utilise ces nouveautés. Ça se fait avec l’option -std=. Par exemple, pour des fonctionnalités de C++17:

g++ hello.cpp -c -std=c++17
g++ hello.o -o hello

La compilation : quelques options courantes.

Mode debug et release

Quand les programmes deviennent complexes et plein de bugs, les développeurs utilisent des outils de debuggage pour aider à leur suppression. Il faut pour cela que le code ait été compilé avec ce qu’on appelle les «symboles de debuggage». On utilise pour cela l’option -g

g++ hello.cpp -c -g
g++ hello.o -o hello

L’inconvénient est que le programme tourne beaucoup plus lentement. Ce n’est pas une version de l’exécutable qu’on va choisir pour l’utiliser fréquemment. C’est une version de développement.

Au contraire, il est possible d’augmenter sensiblement la performance du programme en utilisant l’option d’optimisation -O, en précisant un niveau d’optimisation. Par exemple:

g++ hello.cpp -c -O3
g++ hello.o -o hello

Exécution du programme

Nous avons maintenant notre fichier exécutable. Comment lancer le programme qu’il contient ?

La version courte : sous Linux et Mac, dans le terminal tapez simplement

./hello

Sous Windows, tapez

hello

La version longue : pour lancer un exécutable, par exemple hello, les terminaux vont chercher dans des dossiers prédéterminés si il s’y trouve un exécutable nommé hello. Si vous êtes sous Linux, essayez de taper simplement "hello", sans le "./" dans le terminal pour voir un message d’erreur.

Ces dossiers sont listés dans une variable d’environnement appelée PATH. C’est celle que les utilisateurs Windows ont dû modifier manuellement pour dire au système où se trouve gcc.exe.

Si le binaire à lancer n’est pas trouvé dans un des dossiers listés, il faut spécifier le chemin pour localiser le binaire. Dans le cas présent, le terminal était situé au même endroit que l’exécutable. Le nom du dossier courant est ".", d’où le "./hello". Le même exécutable aurait pu être appelé avec le chemin absolu (cf capture d’écran).

Il n’est pas nécessaire de se trouver dans le dossier où se trouve un exécutable pour le lancer.

QCM (Réponses sur la slide suivante)

C++ est un langage

• compilé
 
• interprété

 

L’option pour que le compilateur m’avertisse de potentielles erreurs est

• -g
 
• -Wall
 
• -warnings

 

Je suis capable de lire un fichier exécutable

• bien sûr !
 
• pas vraiment

 

QCM - Réponses

C++ est un langage

• compilé
 
• interprété

C++ nécessite de transformer les fichiers sources qui contiennent le code C++ en un fichier exécutable, ce qui s’appelle la compilation.

L’option pour que le compilateur m’avertisse de potentielles erreurs est

• -g
 
• -Wall
 
• -warnings

L’option -g est pour le debug. Pour les avertissements, je vous rappelle qu’il est dangereux de les ignorer !

Je suis capable de lire un fichier exécutable

• bien sûr !
 
• pas vraiment

Les fichiers exécutables contiennent des instructions en binaire. Vous ne pouvez pas le lire, à moins que vous ne soyez l’Élu…

Retour au cours Moodle