Big Tuto : Apprenez le C++

Chapitre 5 : Chaînes de caractères - Introduction aux itérateurs

Tutoriel présenté par : Robert Gillard (Gondulzak)
Date d'écriture : 28 septembre 2015
Date de révision : 31 octobre 2015

      Préliminaires 

   Le C++ supporte toujours l'ancien ''style C'' en ce qui concerne la gestion des chaînes de caractères. Bien que l'on conseille actuellement d'éviter de l'utiliser dans les programmes écrits en C++, il n'est pas inutile de revoir quelques-uns de ses concepts pour mieux comprendre la classe <string> de C++ en analysant ce que celle-ci a apporté de plus par rapport a l'ancien style C. wink


         1 – Les chaînes de caractères

      1.1 - Le style C

   Le chapitre 1 de ce big tuto nous a déjà mis en contact avec les chaînes de caractères quand nous avons parlé de l'objet std::cin du flux d'entrée istream dans le programme 004Rpg1,qui demandait à l'utilisateur d'entrer la chaîne «Legends of Meruvia».

   Il faut se rappeler qu'une chaîne de caractères de type C se termine par un caractère nul, soit le caractère '\0'.

   Une constante chaîne, affichée par l'objet std::cout du flux de sortie ostream telle que :

   cout << ''Hello'';

   ... peut être considérée comme un tableau de caractères car déclaré et initialisé avec plusieurs caractères, donnerait

   char tab[ ] = { 'H', 'e', 'l', 'l', 'o', '\0' };

   Cette manière d'initialiser une chaîne étant bien entendu trop sujette à produire des erreurs, le langage C a permis l'écriture suivante, bien plus simple et plus rapide :

   char tab[ ] = ''Hello'';


   Saisir une chaîne de caractères avec cin.get()

   Si nous décidons de réserver une chaîne de caractères d'une grandeur donnée, nous devons utiliser cin.get() pour la saisie de cette chaîne.

   Si nous voulions simplement utiliser cin, nous nous heurterions à deux problèmes de taille:

- Nous risquerions d'écrire au delà des limites du tableau.
- Un espacement serait compris comme fin de chaîne.

 

Retrouvez les projets complets de ce chapitre :

 

   Voyons ceci dans un exemple (Projet 029CStyle1) :

//Projet 029CStyle1
//Saisie d'une chaîne avec cin.get()
#include <iostream>
#include <conio.h>
 
using namespace std;
 
int main()
{
char chaine[7];
 
cout << "Entrez une chaine de 6 caracteres" << endl;
// 1) On entre exactement 6 caractères (azerty)
// le 7eme caractère sera le caractère de fin de chaîne '\0'
cin.get(chaine, 7);
 
cout << "Contenu de la chaine : " << chaine << endl;
cout << endl;
 
_getch();
return 0;
} 

 

   Ce qui donne dans la console :

 

   Si nous avions entré plus de 6 caractères à l'écran, par exemple azertyuiop, seuls les 6 premiers auraient été pris en compte par notre saisie. wink

   Ce qui aurait donné dans la console :


   Les pointeurs et les chaînes de caractères

   Nous savons que les pointeurs sont le plus souvent utilisés pour manipuler des tableaux plutôt que de simples variables.

   Nous allons maintenant voir deux exemples de cette utilisation avec une chaîne de caractères, mais considérons d'abord le programme suivant (Projet 030CStyle2) : 

//Projet 030CStyle2
//Lecture d'une chaîne de caractères utilisant un tableau
#include <iostream>
 
using namespace std;
using uint = unsigned int;
 
int main()
{
char chaine[] = "Bonjour aux lecteurs du big tuto C++";
uint index = 0;
 
while (chaine[index])
{
cout << chaine[index];
++index;
}
 
cout << endl;
 
cin.get();
return 0;
} 

 

   Dis bonjour à Meruv... Heu... frown aux lecteurs du Big Tuto C++ ! angel

 

   Vous voyez que nous utilisons une boucle while dans ce programme. En effet, même si la variable index est initialisée à 0, chaine[index] sera toujours vrai jusqu' à ce qu'elle contienne le caractère de fin de chaîne '\0'. Dès ce moment la condition devient fausse et le programme s'arrête après avoir affiché tous les caractères de la chaîne. cool

   Voyons maintenant le même programme qui utilise un pointeur (Projet 031CStyle3) :

//Projet 031CStyle3
//Lecture d'une chaîne de caractères utilisant un pointeur
#include <iostream>
 
using namespace std;
 
 
int main()
{
char chaine[] { "Bonjour aux lecteurs du big tuto C++" };
 
//On déclare un pointeur null sur un char
char *ptr = nullptr;
 
//Et on l'initialise au début de la chaîne
ptr = chaine;
 
while (*ptr)
cout << *ptr++;
 
cout << endl;
 
cin.get();
return 0;
 
} 

 

   Et on applique le même raisonnement que lors du programme précédent. Tant que le pointeur ne pointe pas sur la case mémoire qui contient le caractère null, on affiche tous les caractères de la chaîne à l'aide du pointeur déréférencé.

   Notre dernier exemple concernant le ''vieux style C'' va utiliser deux pointeurs pour calculer la longueur d'une chaîne de caractères.

   Je sais ce que vous allez me dire. Et strlen() alors?? sad Cette fonction est toute faite pour calculer la longueur d'une chaîne... Pourquoi ne pas l'utiliser ? surprise

   Et bien oui, nous allons très vite en parler mais il est souvent instructif d'être un peu curieux pour voir comment telle fonction ou autre fonctionnalité a été implémentée pour faciliter la tâche de l'utilisateur ? wink Et ce petit programme m'a l'air particulièrement intéressant. cool


     Utiliser deux pointeurs pour calculer la longueur d'une chaîne (Projet 032CStyle4) :

//Projet 032CStyle4
//Calcule la longueur d'une chaîne à l'aide de deux pointeurs
#include <iostream>
#include <conio.h>
 
using namespace std;
using uint = unsigned int;
 
 
int main()
{
// On déclare une chaîne et deux pointeurs
char chaine[80] = "Bonjour aux lecteurs du big tuto C++";
char *ptr1 = nullptr;
char *ptr2 = nullptr;
 
// On initialise la longueur de la chaîne à 0
uint longueurChaine(0);
 
//On fait pointer les deux pointeurs sur le début de la chaîne
ptr1 = ptr2 = chaine;
 
// On incrémente ptr2 jusqu'à la fin de la chaîne
while (*ptr2) *ptr2++;
 
// La soustraction des deux pointeurs donne la longueur de la chaîne
longueurChaine = ptr2 - ptr1;
 
// Et on affiche
cout << "Bonjour aux lecteurs du big tuto C++" << endl;
cout << "La longueur de la chaine est de " << longueurChaine << " caracteres" <<
endl;
 
_getch();
return 0;
 
} 

 

   Ce qui donne dans la console :

 

   La librairie C standard des chaînes de caractères :

   Cette librairie nous procure un ensemble de fonctions opérant sur le style C, concernant les chaînes de caractères. Il faut savoir que C++ inclut actuellement le fichier d'en-tête <cstring> à la place de l'ancien fichier <string.h> pour travailler avec ces fonctions.
   Voici un tableau de quelques fonctions utilisées par C++, contenues dans le fichier d'en-tête <cstring>.
strlen(chaine) Retourne la longueur de la chaîne moins le caractère '\0'
strcmp(chaine1, chaine2)
Compare chaîne1 et chaîne2. 
Retourne 0 si chaine1 == chaine2. 
Une valeur positive si chaine1 > chaine2, et 
une valeur négative si chaine1 < chaine2.
strcat(chaine1, chaine2) Ajoute chaine2 à chaine1 et retourne chaine1.
strcpy(chaine1, chaine2) Copie chaine2 dans chaine1 et retourne chaine1.


   Et bien entendu, la seule ligne :

cout << strlen(chaine);

   ...nous aurait donné la longueur de la chaîne de notre programme précédant.

   Et après ce petit retour intéressant sur le style C concernant les chaînes de caractères, nous pouvons maintenant découvrir la classe <string> de C++. wink

 

   1.2 La classe ''string'' de C++

   Afin de simplifier toutes ces dangereuses manipulations de pointeurs et apporter une importante modification aux anciennes fonctions C (celles-si s'intègrent mal dans une conception OO - Orientée Objet cheeky), C++ a introduit la classe ''string'' dans sa Bibliothèque Standard (Standard Library). Cette classe amène de nouvelles fonctionnalités adaptées à un style de programmation moderne et offrant une plus grande simplicité d'écriture. cool

   Nous aborderons la classe ''string'' de C++ en deux étapes, la première, dans ce chapitre, va nous faire découvrir les différents modes d'initialisation des chaînes de caractères ainsi que quelques fonctions opérant sur celles-ci. Dans la seconde partie, nous verrons des opérations additionnelles de manipulation des chaînes avec C++. Nous verrons ceci en même temps que l'étude des ''containers'' lorsque nous aurons déjà abordé une partie de la POO, mais en attendant, reprenons la suite de notre chapitre.


   Définitions et initialisations de chaînes

   Avant de réaliser toute opération sur les chaînes de caractères, vous devez inclure le fichier d'en-tête <string> au début de votre programme, il s'agit de la library (bibliothèque) qui contient toutes les fonctions nécessaires à la manipulation des chaînes en C++.

#include <string>

 

   Voyons maintenant quelques formes d'initialisation :

string chaine1;                              // Forme la plus simple, initialise une chaîne vide
string chaine2 = chaine1;            // On copie chaine1 dans chaine2
string chaine3 = ''Meruvia'';        // Copie d'une chaîne littérale dans chaine3
string chaine4 ( 5, 'A' );               // Chaine4 contient 5 copies de 'A' donc chaine4 = AAAAA.
 

   Différence entre initialisation directe et copie

   Quand on utilise le signe =, c'est le compilateur qui se chargera d'ajouter l'objet situé à droite du signe dans l'objet situé à gauche. Il s'agit d'une initialisation par ''copie''.

   Si on écrit : chaine3 (''Meruvia''), nous faisons ce qu'on appelle une initialisation ''directe'', déjà connue au moment de la compilation.

 
Opérations diverses sur les chaînes
cout << chaine Ecriture d'une chaîne sur le flux de sortie ''ostream''
cin >> chaine  Lecture d'une chaîne à partir du flux d'entrée ''istream''
getline (cin, chaine) Lecture d'une ligne à partir du flux d'entrée ''istream''
chaine.empty() Retourne true si la chaîne est vide, false dans le cas contraire
chaine.size() Retourne le nombre de caractères de la chaîne
chaine[ n ] Retourne une référence du caractère situé à la position n de chaine
chaine1 + chaine2  Concaténation de deux chaînes
chaine1 = chaine2 Remplace les caractères de chaine1 par une copie de chaine2
chaine1 == chaine2 Egalité des chaînes si elles contiennent les mêmes caractères
chaine1 != chaine2 Inégalité de deux chaînes
 
   Les différents signes de comparaison <, <=, >, >=, sont applicables aux chaînes de caractères. wink


   Quelques exemples de lecture et d'écriture de chaînes

   Dans ce premier exemple (Projet 033Strings1), nous allons premièrement acquérir une chaîne à l'écran et ensuite nous demanderons à l'utilisateur d'entrer un nombre quelconque de mots avec une condition qui teste le flux d'entrée jusqu'à EOF (End Of File)
//Projet 033Strings1
//Entrées-Sorties de strings
#include <iostream>
#include <conio.h>
#include <string>
 
using namespace std;
 
int main()
{
string nom; // Une chaîne vide
 
cout << "Entrez un nom d'ennemi suivi de RETURN" << endl;
cin >> nom;
cout << "Le mot est " << nom << endl;
cout << endl;
 
string ennemi;
cout << "Maintenant entrez quelques noms d'ennemis" << endl;
cout << "La condition EOF sera prise en compte (CTRL-Z, par exemple)" << endl;
 
while (cin >> ennemi)
cout << "Vous avez entre " << ennemi << endl;
 
return 0;
 
} 

 

   Remarquez la condition d'entrée : while (cin >> ennemi) qui teste EOF à chaque tour de boucle ! wink
   Attention que dans ce cas aussi, comme pour l'initialisation d'une chaîne avec char en C, un caractère d'espacement est pris en compte et termine la chaîne.

   Ce qui, par exemple, donne dans la console :

 

   Pour entrer une ligne complète, nous devons utiliser ''getline'', dont nous avons parlé dans le chapitre 1, mais qui, dans une condition de test de flux d'entrée donnerait (Projet 034Strings2) :

//Projet 034Strings2
//Lit une ligne jusqu'à EOF
#include <iostream>
#include <conio.h>
#include <string>
 
using namespace std;
 
int main()
{
string nArme; // Une chaîne vide
 
cout << "Entrez le nom des armes que vous avez ramassees" << endl;
cout << "La condition EOF sera prise en compte apres chaque ligne" << endl;
cout << "(CTRL - Z, par exemple)" << endl << endl;
 
while (getline(cin, nArme))
cout << "Vous avez entre " << nArme << endl << endl;
 
return 0;
 
} 

 

   Ce qui, par exemple, afficherait dans la console :

 

 

   Autres exemples d'opérations sur les chaînes :

   En ce qui concerne la comparaison des chaînes de caractères, nous retiendrons que

- Si deux chaînes ont des longueurs différentes et que chaque caractère dans la chaîne la plus courte est égal au caractère correspondant de la chaîne la plus longue, alors la chaîne la plus courte est plus petite que la chaîne la plus longue.

- Si dans deux chaînes quelconques, les caractères situés aux positions correspondantes diffèrent, alors le résultat de la comparaison des chaînes sera le résultat de la comparaison de ces caractères.

 

   Voyons ceci par un exemple (Projet 035Strings3) :

//Projet 035Strings3
//Autres opérations sur les chaînes"
#include <iostream>
#include <string>
 
using namespace std;
 
int main()
{
string chaine1("Le Prince des ");
string chaine2("Royaumes du Nord");
 
cout << "chaine1 = " << chaine1 << endl;
cout << "chaine2 = " << chaine2 << endl << endl;
 
// Concaténation de deux chaînes
chaine1 += chaine2;
 
cout << "On ajoute chaine2 a chaine1" << endl;
cout << "chaine1 = " << chaine1 << endl << endl;
 
// Comparaison de chaînes
string chaine3("Rabidja");
string chaine4("Rabidja");
 
cout << "chaine3 = Rabidja" << endl;
cout << "chaine4 = Rabidja" << endl;
 
if (chaine3 == chaine4)
cout << "chaine3 = chaine4";
else cout << "Les chaines sont de longueurs différentes";
cout << endl << endl;
 
chaine1 = "Assourbanipal";
chaine2 = "Assourdan";
cout << "chaine1 = " << chaine1 << " et contient " << chaine1.size() << " caracteres" << endl;
cout << "chaine2 = " << chaine2 << " et contient " << chaine2.size() << " caracteres" << endl;
 
if (chaine1 < chaine2)
cout << "chaine1 < chaine2";
else cout << "chaine2 < chaine1";
cout << endl;
 
cin.get();
return 0;
 
} 

 

   Il n'y a rien de compliqué dans cet exemple. Remarquez simplement au bas de la console que malgré le fait que chaine1 contient 13 caractères et chaine2, 9 caractères, chaine1 est plus petite que chaine2. En effet, seul compte le premier caractère différent dans chaque chaîne et b < d.

 

   Ce qui donne dans la console :

 

 

   Nous allons maintenant voir un petit programme qui lit tous les caractères d'une chaîne et vous pourrez le comparer aux exemples des projets 030CStyle2 et 031CStyle3. Vous verrez que la nouvelle forme d'écriture est bien plus concise et plus parlante (Projet 036Strings4) :

//Projet 036Strings4
//Lecture de tous les caractères d'une chaîne C++
#include <iostream>
#include <string>
 
using namespace std;
 
 
int main()
{
string arme( "Double Hache tranchante de la Colere de Thor" );
cout << "Double Hache tranchante de la Colere de Thor" << endl;
 
for (auto caract : arme)
cout << caract;
 
cout << endl;
cin.get();
return 0;
 
} 

 

   Donc en deux lignes nous disons : pour chaque caractère de la chaîne arme, écrire ce caractère.
   Le type ''char'' de chaque caractère est bien entendu déterminé par le compilateur à l'aide du spécificateur de type ''auto''.

  Ce qui donne dans la console :

 

   La librairie cctype

    ''cctype'' est une bibliothèque de fonctions permettant différents contrôles des chaînes de caractères.
   Pour utiliser les fonctions de la library ''cctype'', nous inclurons donc celle-ci en haut d'un programme comme nous le faisons pour la lib ''string''.

#include <cctype>

   Bien que cctype contienne les mêmes fonctions que ctype.h, ces fonctions sont écrites dans un style spécifique aux programmes C++. Quoi qu'il en soit, C++ recommande toujours fortement d'inclure les nouvelles librairies ne contenant plus l'extension ''.h''. wink


Fonctions de la library cctype

isalnum (c) vrai si c est une lettre ou un digital
isalpha (c) vrai si c est une lettre
iscntrl (c) vrai si c est un caractère de contrôle
isdigit (c) vrai si c est un digital
isgraph (c) vrai si c n'est pas un espace mais est un caractère imprimable
islower (c)  vrai si c est une minuscule
isprint (c) vrai si c est un caractère imprimable
ispunct (c) vrai si c est un caractère de ponctuation
isspace (c) vrai si c est un espace quelconque
isupper (c) vrai si c est une majuscule
isxdigit (c) vrai si c est un digital hexadécimal
tolower (c)  retourne le caractère minuscule de c majuscule
toupper (c) retourne le caractère majuscule de c minuscule


   Un exemple de programme avec la fonction ''toupper'' de la librairie cctype (Projet 037Strings5) :

//Projet 037Strings5
//Mise en majuscules des caractères d'une chaîne
#include <iostream>
#include <string>
#include <cctype>
 
using namespace std;
 
int main()
{
string arme("Double Hache tranchante de la Colere de Thor");
cout << "Double Hache tranchante de la Colere de Thor" << endl << endl;
 
cout << "On utilise la fonction 'toupper' de la librairie cctype" << endl;
 
for (auto &caract : arme)
caract = toupper(caract);
 
cout << arme << endl;
 
cin.get();
return 0;
}

 

   Ce programme a transformé en majuscules tous les caractères de la chaîne du programme précédent.

Attention : &caract est une référence, donc l'assignation caract = toupper(caract) change le caractère à l'intérieur de la chaîne.

   Ce qui donne dans la console :

 

   Voilà en ce qui concerne les chaînes de caractères, il est temps de faire une brève introduction aux itérateurs.

 

   1.3 Introduction aux itérateurs

   Nous savons que nous pouvons accéder à tous les éléments d'une chaîne ou d'un vector à l'aide de variables. Il existe cependant un mécanisme plus général connu sous le nom d'itérateurs,qui permet de réaliser les mêmes opérations. Bien que les itérateurs ne s'appliquent qu'à toutes les libraries de ''containers'', ils peuvent également être utilisés avec les chaînes, même si celles-ci ne sont pas reprises comme un type de container. wink

   Retenons dès à présent qu'un container est une classe générique qui est conçue pour le stockage de données et que, comme signalé précédemment nous en parlerons plus en profondeur au cours de l'étude de la POO.

   Au même titre qu'un pointeur, un itérateur donne un accès indirect à un objet mais dans le cas d'un itérateur, cet objet sera toujours un container ou une chaîne.


      Utilisation d'itérateurs

   Contrairement aux pointeurs, nous n'avons pas besoin de connaître l'adresse d'un itérateur pour en obtenir un, car les types de containers qui utilisent des itérateurs ont des membres qui retournent des itérateurs. Deux membres particuliers de ces types s'appellent begin et end (non ce n'est pas un cours de Pascal... indecision).

   Exemple : auto debut = chaine.begin(), fin = chaine.end();

   Ici, le compilateur détermine le type de ''debut'' et ''fin'' grâce au spécificateur de type ''auto''. Le membre begin retourne un itérateur qui représente le premier élément ou caractère tandis que end retourne un itérateur qui se réfère non pas au dernier mais à l'élément suivant le dernier. ''One past the end'' comme l'appelle la littérature anglophone. wink

   En général, nous ne connaissons pas (et on n'a pas besoin de le connaître cheeky) le type précis d'un itérateur, le spécificateur de type ''auto'' s'en charge seul comme nous allons le voir dans l'exemple suivant. Nous allons voir également comment nous pouvons gérer ses membres begin et end en modifiant le projet 037Strings5.


      Opérations sur les itérateurs (Projet 038iterator1)     

//Projet 038iterator1
//Mise en majuscules des caractères d'une chaîne
#include <iostream>
#include <string>
#include <cctype>
 
using namespace std;
 
int main()
{
string arme("Double Hache tranchante de la Colere de Thor");
cout << "Double Hache tranchante de la Colere de Thor" << endl << endl;
 
cout << "On utilise la fonction 'toupper' de la librairie cctype" << endl;
cout << "et on parcourt la chaine a l'aide d'un iterateur" << endl;
 
for (auto it = arme.begin(); it != arme.end(); ++it)
*it = toupper(*it); //Transforme les caractères en majuscules
 
cout << endl;
cout << arme << endl;
 
cin.get();
return 0;
} 

 

   Deux choses importantes sont à relever de cet exemple :

- Puisque ''end'' retourne un itérateur qui se réfère à un élément suivant le dernier (One past the end), on s'habituera à écrire it != arme.end() et non pas it < arme.end(), non pas parce que c'est faux mais il s'agit plutôt d'une convention entre programmeurs qui utilisent les containers et que le fait d'écrire it != arme.end() teste automatiquement si la chaîne n'est pas vide. wink
- Pour transformer les caractères, on remarquera que les itérateurs se comportant comme des pointeurs, nous devons les déréférencer.


   Ce qui affiche dans la console :

 

   Bien, admettons maintenant que nous ayons une phrase toute écrite en lettres minuscules et que nous voulions écrire le premier caractère en majuscule, le programme ci-dessus deviendrait (Projet 039iterator2) :

//Projet 039iterator2
//Mise en majuscule du 1er caractère d'une chaîne
#include <iostream>
#include <string>
#include <cctype>
 
using namespace std;
 
int main()
{
string monstre("le loup-garou de la foret de Perdagne");
cout << "le loup-garou de la foret de Perdagne" << endl << endl;
 
cout << "On utilise la fonction 'toupper' de la librairie cctype" << endl;
cout << "begin renvoie un iterateur sur le 1er element de la chaine" << endl;
 
if (monstre.begin() != monstre.end()) // On s'assure que la chaîne n'est pas vide
{
auto it = monstre.begin();
*it = toupper(*it); //Transforme le 1er caractère en majuscule
}
 
cout << endl;
cout << monstre << endl;
 
cin.get();
return 0;
} 

 

   Ce qui donne dans la console :

 

   Types d'itérateurs

   Bien que nous n'ayons pas besoin de connaître le type d'un itérateur, les libraries utilisant les itérateurs ont cependant défini des types nommés iterator et const_iterator. Ces types spéciaux représentent les types actuels d'itérateurs. Voici, à titre d'exemples, la forme utilisée par ces types pour représenter des iterateurs se rapportant à des vectors ou des chaînes de caractères.

   vector<int>::iterator it;           // it peut lire et écrire des élément vector<int>
   string::iterator it;                    // it peut lire et écrire des caractères dans une chaîne

   vector<int>::const_iterator it;           // it peut lire mais ne peut pas écrire des éléments dans le vector
   string::const_iterator it;                    // it peut lire mais ne peut pas écrire de caractère dans une chaîne

 

   Et j'ajouterai pour terminer cette introduction aux itérateurs que les types retournés par begin et end dépendent bien entendu des objets sur lesquels les itérateurs opèrent.

   En effet, considérons un vector d'entiers et un vector d'entiers constants soit :

   vector<int> monVecteur1;
   const vector<int> monVecteur2;

   Il est bien entendu que dans les expressions :

   auto it1 = monVecteur1.begin();             // it1 sera de type vector<int>::iterator
   auto it2 = monVecteur2.begin();            // it2 sera de type vector<int>::const_iterator

   Et qu'il est quand-même plus simple et plus lisible d'utiliser un spécificateur de type tel que ''auto'' (pour ceux qui se se seraient posés la question de son utilité cheeky) pour écrire par exemple :

   auto it2 = monVecteur2.begin() plutôt que vector<int>::const_iterator it2 = monVecteur2.begin()


   Voilà, c'est tout pour ce long chapitre (oui je sais, il y a un effort à faire quant à leur longueur... blush), mais vous admettrez que plus il y a d'exemples, mieux c'est et je me vois quand-même dans l'obligation d'afficher leurs résultats dans la console. wink

  Comme annoncé dans le forum avant l'écriture de ce tutoriel, je n'aborderai pas ici les ''Contrôles de Programme'' (boucles for, switch case, while, do while... etc ). Ces contrôles seront donc supposés connus par l'étude d'un cours de C ou de tutoriels existants sur le sujet. Je dois néanmoins dire que l'on pourrait trouver quelques différences subtiles dans certains contrôles du C++ par rapport au langage C mais j'en parlerai lors de l'un ou l'autre exemple dans lequel le cas pourrait se présenter. wink

@ bientôt pour le chapitre 6 : Les fonctions 1 angel

Gondulzak.
  

 

 

 

Connexion

CoalaWeb Traffic

Today108
Yesterday282
This week902
This month3195
Total1742402

19/04/24