Date de première publication : 2013/06/10
Ce premier TP est là pour vous montrer les spécificités de C++ par rapport au C. Nous n'abordons pas encore la notion d'objet.
Nous utilisons un compilateur "récent" qui supporte nativement la norme 2014 (2011 améliorée).
1. Du C au C++
1.1. "Hello world"
Voici votre premier programme C++ :
Si l'on compare avec un programme C :
- les
#include
ne mentionnent plus l'extension.h
(ou autre.hpp
) - l'instruction
printf()
est avantageusement remplacée par un truc qui s'appellestd::cout
dont la syntaxe est un peu bizarre mais qui est relativement pratique : les éléments sont donnés les uns à la suite des autres séparés par l'opérateur<<
(il n'y a plus la chaîne de format) std::endl
est la séquence particulière qui signifie "retour à la ligne" (bon, ok, c'est plus verbeux que'\n'
qui reste utilisable)- Remplacer le
2
par la variablei
, et ensuitei/10.0
Le reste est similaire au C. Effectuez les opérations suivantes :
- Compilez ce petit programme avec g++ (et non gcc, ce qui est une erreur classique)
- Ajoutez maintenant les options
-Wall -Wextra
- Enlever les warnings en utilisant les paramètres muets, c'est-à-dire en omettant les noms des paramètres qui ne sont pas utilisés
Tous les warnings doivent être pris en compte, comme en C.
En C++, il est relativement courant de déclarer les variables de boucle dans la structure elle-même (attention, cela peut aller à l'encontre d'un guide de style) :
Cette manière de faire peut aller à l'encontre d'un guide de style et certains compilateurs (notamment MS C++) peuvent avoir une gestion par défaut de la durée de vie de telles variables)
1.2. Entrée standard...
- Compilez et exécutez le programme suivant
- Afficher les réponses
Demander également le nom de la personne et affichez successivement le nom et le prenom, puis la concatenation du nom, du prénom séparé par un :
1.3. ... et chaînes de caractères
std::string
est un type qui représente la chaîne de caractères en C++. Vous ne devriez plus JAMAIS avoir besoin
(sauf TP à vocation casse-pied) de faire appel au char *
. La fonction main()
vient du C, c'est pour cela que son prototype n'utilise pas std::string
mais char *
Manipuler les "objets" standards avec le préfixe std::
peut être un peu pénible MAIS c'est obligatoire si vous avez TP avec Alexis et Jeremy.
On peut ajouter une instruction qui permet de s'en débarasser :
using namespace std;
(C'est le U word) ou using std::cout;
(c'est mieux).
1.4. Petits exercices sur les chaînes
- Demander deux chaînes de caractères à l'utilisateur et afficher la plus petite des deux (ordre lexicographique)
- Afficher la longeur de la chaîne saisie par l'utilisateur
1.5. Tableaux et constantes
Vous pouvez compiler ce programme en C et en C++, en mettant de côté les appels à std::cout
.
Si vous souhaitez conserver l'affichage à l'écran, il est possible d'utiliser la fonction printf
car tout programme C++ peut
faire appel aux bibliothèques C, seuls les noms des fichiers entête changent : par exemple, stdlib.h
devient cstdlib
.
1.6. Surcharge de fonction
Placer ce code dans un fichier d'extension .c
et compiler avec gcc
. Observer les erreurs.
Si le fichier est d'extension .cpp
et compilé avec gcc
ou bien si le fichier d'extension .c
est compilé avec g++
, vous n'aurez pas ces messages d'erreurs !
2. Chaines de caractères
Une fiche sur les chaînes de caractères est disponible.
Exécutez le code suivant et regardez ce que cela donne avec les différentes versions de s
:
Exécutez avec valgrind pour relever les éventuelles erreurs de contexte (vous pouvez également résoudre ces erreurs de contexte).
Pour exécuter avec valgrind, il faut que le code à profiler ait été compilé avec l'option -g
3. Références
En C, il y a deux manières d'accéder à une variable : par sa valeur ou par son adresse en la déréférençant. Le C++ ajoute une nouvelle manière d'accéder à une variable en la référençant, c'est-à-dire en en faisant un alias.
3.1. Premières manipulations
- Compiler et exécuter le programme précédent.
- Afficher les adresses de
a
et der
- Que se passe-t-il si
r
n'est pas initialisée ? - Compiler et exécuter le programme suivant. A-t-on le comportement attendu ?
- BONUS : Que se passe-t-il si on essaie de donner le même nom aux fonctions
fonction1()
etfonction2()
?
La référence n'est pas un type différenciant pour le compilateur pour déterminer la surcharge
3.2. Échange de variables
Essayer le code suivant :
Écrire une fonction qui permet l'échange de deux variables de type int
- avec des pointeurs
- avec des références
Comparer la facilité d'écriture et de compréhension avec les références.
3.3. Une référence référence ...
Que se passe-t-il avec ce bout de code ? Comment détecter l'erreur à tous les coups ?
3.4. mais pas n'importe comment
3.5. Une référence "constante"
Que se passe-t-il avec le code suivant ?
La référence est dite "constante", ce qui est un abus de langage. En fait, la variable référencée est considérée comme constante : accessible en lecture mais pas en écriture.
3.6. Une référence sur une constante
Que se passe-t-il avec le code suivant ?
Il faut une référence "constante" pour référencer la constante
Corriger l'erreur !
4. Pointeurs et allocation mémoire
En C++, on n'utilise plus les fonctions malloc()
et free()
mais les opérateurs new
et delete
. L'opérateur delete
existe en deux versions suivant que le pointeur est associé à une zone mémoire simple ou une zone mémoire contiguë.
Pour initialiser un pointeur, le C++ introduit une valeur spéciale nullptr
:
Nous verrons plus tard comment gérer une allocation mémoire impossible
Exécutez valgrind
sur les deux exemples suivants et corrigez-les en décommentant la libération mémoire ! Voici le premier :
Voici le second :
Que se passe-t-il dans ce dernier exemple si vous oubliez les crochets ?
Notez la présence du mot-clé auto
dont le sens a été modifié depuis le C qui permet de demander au compilateur de déduire le bon type de variable ! Ne surutilisez pas cet opérateur car cela peut nuire à la lisibilité du code.
4.1. C++, un langage objet ?
Finalement, on va faire un tout petit peu d'objet... Compiler et exécuter le programme suivant :
Regarder les erreurs obtenues si vous faites les choses suivantes :
- enlever le mot
public
- enlever le point virgule en fin de classe
- compiler avec
gcc
?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
