Chapitre 1
BASES DU LANGAGE C++
 
 
Précédent Suivant
 

Bases du langage C++
Syntaxe
* Dans cette partie, uniquement les aspects procéduraux
* Aspects objet vus en deuxième partie
* Syntaxe similaire au C
* Instructions terminées par ";"
* Commentaires
* "//" pour une seule ligne
* "/*...*/" pour plusieurs lignes
* Opérateurs identiques
* Structures de contrôle identiques
* Sensible à la casse
* Variables fortement typées
Variables
* Toujours préciser le type à la déclaration
* type nom_variable;
* Ensuite, le type de la variable ne peut plus changer
* Intérêt: contrôle tout au long du code, ce qui empêche les erreurs
* Possibilité de fournir une valeur initiale
* type nom_variable = valeur;
* Toujours déclarer une variable
* Variable globale
* Paramètre de fonction
* Variable locale
* Déclarer une constante: mot-clé "const"
* const int a = 12;
Types élémentaires (1/2)
* Entier: [ signed / unsigned ] short / int / long
* Domaine de valeurs dépendant de l'architecture matérielle
* Par exemple, sur un Intel 32 bits
* short ==> 16 bits / 2 octets
* int ==> 32 bits / 4 octets
* long ==> 64 bits / 8 octets
* Entier signé par défaut
* Signé = peut prendre une valeur négative
* int x ? signed int x ==> nombre entier pouvant être négatif
* unsigned int x ==> nombre entier positif
Types élémentaires (2/2)
* Caractère: [ signed / unsigned ] char
* Valeur délimitée par le symbole "'"
* char x = 'a';
* Equivalent à un nombre
* Code ASCII / 1 octet
* Exemple: 'a' ? 97
* Flottant: float / double
* double ==> plus de précision, mais plus de place en mémoire
Conversion de type
* Possibilité de convertir une valeur d'un type à un autre
* Si la procédure est prévue en standard
* Ou si la procédure a été définie par le développeur
* Surcharge d'opérateur
* Opérateur de conversion
* Conversion implicite
* Quelques conversions sont évidentes
* int x = 5;
double y = x;
* Conversion explicite ==> opérateur "(type)"
* Comme le contrôle des types doit être garanti
* La plupart des conversions sont interdites implicitement
* double y = 2.5;
int x = (int)y;
Portée des variables
* Portée limitée au bloc d'instructions (entre "{" et "}")
* Que ce soit une fonction, une boucle, une condition...
* Exemple
int x = ...;
if (x == 3) {
int y = 2;
}
cout << y; ==> erreur
* Variable détruite à la sortie du bloc
Opérateurs classiques
* Arithmétique: +, -, *, /, % (modulo)
* Incrémentation / décrémentation: --, ++
* i++ / ++i ? i = i+1
* i-- / --i ? i = i-1
* Affectation: =, +=, -=, *=, /=, %=
* i += 3 ? i = i+3
* Logique: && (et), || (ou), ! (non)
* Comparaison: ==, <, >, <=, >=, !=
Structures de contrôle
* Bloc d'instructions délimité par "{" et "}"
* Facultatif si une seule ligne
* if (x == 1) y = 2; ? if (x == 1) { y = 2; }
* Structures conditionnelles
* if (test1) { action1 }
else if (test2) { action2 }
else { action3 }
* switch (variable) {
case valeur1: action1 break;
case valeur2: action2 break;
default: action3
}
* Structures de boucle
* while (test) { action }
* do { action } while (test);
* for (depart; test; suivant) { action }
Tableaux
* Déclaration (et création) d'un tableau
* type nom_tableau[taille];
* Possibilité de remplir le tableau à la déclaration
* type nom_tableau[] = { valeur_1,valeur_2,... };
* Accès (en lecture ou écriture) à un élément
* A l'aide de son indice i: nom_tableau[i]
* Eléments numérotés à partir de 0
* Déclaration (sans création) d'un tableau
* type * nom_tableau;
* Voir les pointeurs
* "Tableau constant" = valeur constante des éléments
* const type * nom_tableau;
* const type nom_tableau[taille];
Chaînes de caractères
* Chaîne de caractères = tableau de caractères
* char nom[] = "Bruno";
* Mais un caractère spécial (code ASCII = 0) termine le tableau
* Le tableau "nom" contient 6 caractères
* char nom[] = { 'B', 'r', 'u', 'n', 'o', 0 };
* Autre représentation en C++: le type "string"
* string nom = "Bruno";
* Opérateur de concaténation: nom = nom + " Nawouak";
* Taille d'une chaîne: unsigned n = nom.length();
* Tableau de caractères: const char * tab = nom.c_str();
Bibliothèque standard
* De nombreuses fonctionnalités fournies en standard
* Types, fonctions, variables globales, constantes...
* Pour les utiliser
* Inclure l'entête contenant la fonctionnalité
* Voir la documentation
* Pour les chaînes de caractères
* #include <string>
* Fonctionnalité précédée du préfixe "std::"
* Exemple: std::string
* Pour éviter d'écrire le préfixe dans un bloc
* using namespace std;
Flux d'entrée/sortie
* Entête: #include <iostream>
* Sortie console = flux = variable globale "cout"
* cout << x; ==> affiche le contenu de "x" sur la console
* cout << endl; ==> retour à la ligne
* Possibilité d'enchaîner: cout << x << endl;
* Entrée console = flux = variable globale "cin"
* cin >> x; ==> récupère l'entier saisi dans "x"
* Fichier = flux
* Entête: #include <fstream>
* Fichier d'entrée: ifstream
* Fichier de sortie: ofstream
Manipuler une chaîne comme un flux
* Entête: #include <sstream>
* Ecriture dans un flux "stringstream"
stringstream ss;
ss << 10 << '/' << 9 << '/' << 2012;
string date = ss.str(); ==> récupération de la chaîne
* Lecture d'un flux chaîne
stringstream ss;
ss << "3 7 13 27";
int x;
int somme = 0;
for (unsigned i = 0; i < 4; ++i) {
ss >> x;
somme += x;
}
Fonctions (1/2)
* Permettent de factoriser / réutiliser du code
* Portions de code associées à un nom
* Reçoivent des arguments en entrée
* Retournent éventuellement une valeur en sortie
* type_retour nom(arguments) {
action;
return resultat;
}
* Pas de retour: type_retour = void
* Exemple
int ajouter(int a,int b) {
int c = a + b;
return c;
}
Fonctions (2/2)
* Passage par valeur / copie
* int f(int x)
* L'argument "x" est une copie
* Modification limitée à "f"
* int ajouter1(int a,int b)
{ return (a + b); }
* w = ajouter1(u,v);
* Passage par référence
* int f(int & x)
* L'argument "x" est un alias
* Modification répercutée hors de "f"
* void ajouter2(int a,int b,
int & c)
{ c = a + b; }
* ajouter2(u,v,w);
Organisation de la mémoire
* Variable = alias d'une zone mémoire allouée
pour stocker des données d'un type défini
* int x; ==> zone mémoire étiquetée "x" pour stocker un entier
* Programme = deux zones pour stocker des données
* La pile
* Mémoire pour les variables locales (et les arguments de fonctions)
* Allocation mémoire automatique à partir de la déclaration
* A chaque appel de fonction, les variables locales sont empilées
* A la fin de la fonction, ces variables sont dépilées
* Le tas
* Mémoire préservée durant toute la durée du programme
* Pas d'organisation prédéfinie des zones allouées
* La mémoire allouée dans le tas survit après la fonction qui l'a créée
Allocation mémoire
* Pour créer une zone mémoire sur le tas: instruction "new"
* new int ==> création d'un entier
* new int[10] ==> création d'un tableau de 10 entiers
* "new" retourne l'adresse mémoire de la zone allouée
==> le "pointeur"
* Déclaration d'un pointeur: type * nom_pointeur;
* int * px = new int;
* int * px = new int[10];
* Libérer une zone mémoire
* Elément simple: delete px;
* Tableau d'éléments: delete [] px;
Accès à la mémoire
* Accès à la valeur référencée par un pointeur: opérateur "*"
* *px ==> valeur entière référencée par "px"
* int j = *px; ==> OK
* int j = px; ==> non, car "px" est un pointeur
* Obtenir l'adresse d'une variable: opérateur "&"
* int i = 5;
* int * px = &i;
* *px = 12;
Exemple: les deux mémoires
void f(void) {
int x = 3;
int y = 7;
int * px = new int;
*px = 13;
}
Arithmétique des pointeurs (1/2)
* Un tableau est représenté par un pointeur
* int tab1[] = { 1,2,3,4,5 };
* int * tab2 = tab1;
* Différence: "tab1" est un pointeur constant
* Arithmétique
* *tab2 ==> valeur entière pointée par "tab2"
* Equivalent à "tab2[0]"
* De manière générale: tab2[i] ? *(tab2+i)
* tab2+i = adresse de "tab2" décalée "i" fois
* = de la taille en octets d'un élément
* sizeof(type) = taille en octets d'un type de données
Arithmétique des pointeurs (2/2)
int tab[] = { 3,5,7,13,27 };
int * px;