>C++ 1< |
INCOMPATIBILITES ENTRE C ET C++
NOUVELLES POSSIBILITES DU C++
Dans ce premier chapitre sont exposés les "plus" et les différences du C++ par
rapport au C, sans toutefois aborder la programmation orientée objet (P.O.O.) qui sera
vue lors dun prochain chapitre.
I- COMMENTAIRES
En C++, les commentaires sécrivent derrière un // et se terminent avec la fin de
la ligne.
Exemple: void main() // ceci est un commentaire
{ // noter que le qualificatif "void" est obligatoire
int n=2; // devant "main()"
}
II- LE QUALIFICATIF " CONST "
En C++, de telles déclarations de tableaux sont autorisées:
const int taille = 5;
char tab1[taille];
float tab2[taille + 1][taille *2];
III- DECLARATION DES VARIABLES
En C++, on peut déclarer les variables LOCALES au moment où on en a besoin. Si une
variable locale est déclarée au début dun bloc, sa portée est limitée à ce
bloc.
Exemple: void main()
{
for ( int i = 0;i<10;i++ ) // la variable i est connue de toute la fonction { //
"main()"
int j; // la variable j nest connue que du bloc
...;
...;
}
}
Ce exemple est équivalent à:
void main()
{
int i;
for ( i = 0;i<10;i++ ) // la variable i est connue de toute la fonction { //
" main() "
int j; // la variable j nest connue que du bloc
...;
...;
}
}
Cette possibilité autorise une gestion plus précise de la mémoire, mais peut nuire à
la structuration des programmes.
IV- LES NOUVELLES POSSIBILITES DENTREES/SORTIES
On peut utiliser en C++ les fonctions dentrées/sorties classiques du C (printf,
scanf, puts, gets, putc, getc ...), à condition de déclarer le fichier den-tête
stdio.h.
Il existe de nouvelles possibilités en C++, à condition de déclarer le fichier
den-tête iostream.h.
Ces nouvelles possibilités ne nécessitent pas de FORMATAGE des données.
Sortie sur écran: lopérateur cout:
Exemples: cout << "BONJOUR"; // équivalent à puts("BONJOUR");
int n = 25;
cout << "Valeur: "; // équivalent à puts("Valeur");
cout << n; // équivalent à printf("%d",n);
On peut encore écrire directement:
cout <<"Valeur:" << n;
cout <<"\n "; // pour aller à la ligne
char c = a;
cout << c; // affiche le caractère, il faut utiliser
// printf (formatage), pour obtenir le code ASCII
Cette notation sera justifiée lors du chapitre sur les flots.
Lopérateur cout permet dafficher des nombres entiers ou réels, des
caractères, des chaînes de caractères, des pointeurs autre que de type *char (valeur de
ladresse).
Exemple (à tester) et exercice I-1:
#include <iostream.h>
#include <conio.h>
void main()
{
int i,n=25,*p;
char *tc="On essaie cout !";
float x = 123.456;
cout<<"BONJOUR\n";
cout<<tc<<"\n";
cout<<"BONJOUR\n"<<tc<<"\n";
cout<<"n= "<<n<<" x= "<<x<<" p=
"<<p<<"\n";
getch() ;
}
Saisie clavier: lopérateur cin:
Exemples: int n;
cout<<"Saisir un entier: ";
cin >> n; // équivalent à scanf("%d",&n);
int a, b;
cin >> a >> b; // saisie de 2 entiers séparés par un Retour Charriot
Cette notation sera justifiée lors du chapitre sur les flots.
Lopérateur cin permet de saisir des nombres entiers ou réels, des caractères, des
chaînes de caractères.
Exemple (à tester) et exercice I-2:
Tester cet exemple plusieurs fois, notamment en effectuant des saisies erronées de sorte
dévaluer les " anomalies " de fonctionnement de cin.
#include <iostream.h>
#include <conio.h>
void main()
{
int n;
char tc[30],c;
float x;
cout<<"Saisir un entier:";
cin>>n;
cout<<"Saisir un réel:";
cin>>x;
cout<<"Saisir une phrase:";
cin>>tc;
cout<<"Saisir une lettre:";
cin>>c;
cout<<"Relecture: "<<n<<" "<<x<<"
"<<tc<<" "<<c<<"\n"; getch() ;
}
V- LES CONVERSIONS DE TYPE
Le langage C++ autorise les conversions de type entre variables de type char, int, float,
double:
Exemple:
void main()
{
char c=0x56,d=25,e;
int i=0x1234,j;
float r=678.9,s;
j = c; // j vaut 0x0056
j = r; // j vaut 678
s = d; // s vaut 25.0
e = i; // e vaut 0x34
}
Une conversion de type float --> int ou char est dite dégradante
Une conversion de type int ou char --> float est dite non dégradante
VI- LES CONVERSIONS DE TYPE LORS DAPPEL A FONCTION
Le C++, contrairement au C, autorise, dans une certaine mesure, le non-respect du type des
arguments lors dun appel à fonction: le compilateur opère alors une conversion de
type.
Exemple: double ma_fonction(int u, float f)
{
.....; // fonction avec passage de deux paramètres
.....;
}
void main()
{
char c; int i, j; float r; double r1, r2, r3, r4;
r1 = ma_fonction( i, r ); // appel standard
r2 = ma_fonction( c, r); // appel correct, c est converti en int
r3 = ma_fonction( i, j); // appel correct, j est converti en float
r4 = ma_fonction( r, j); // appel correct, r est converti en int
// et j est converti en float
}
Exercice I-3:
Ecrire une fonction float puissance(float x,int n) qui renvoie xn. La mettre en oeuvre en
utilisant les propriétés de conversion de type.
VII- LES ARGUMENTS PAR DEFAUT
En C++, on peut préciser la valeur prise par défaut par un argument de fonction. Lors de
lappel à cette fonction, si on omet largument, il prendra la valeur indiquée
par défaut, dans le cas contraire, cette valeur par défaut est ignorée.
Exemple: void f1(int n = 3) // par défaut le paramètre n vaut 3
{
....;
}
void f2(int n, float x = 2.35) // par défaut le paramètre x vaut 2.35
{
....;
}
void f3(char c, int n = 3, float x = 2.35) // par défaut le paramètre n vaut 3
{ // et le paramètre x vaut 2.35
....;
}
void main()
{
char a = 0; int i = 2; float r = 5.6;
f1(i); // largument n vaut 2, linitialisation par défaut est ignorée
f1(); // largument n prend la valeur par défaut
f2(i,r); // les initialisations par défaut sont ignorées
f2(i); // le second paramètre prend la valeur par défaut
// f2(); interdit
f3(a, i, r); // les initialisations par défaut sont ignorées
f3(a, i); // le troisième paramètre prend la valeur par défaut
f3(a); // le deuxième et la troisième paramètres prennent les valeurs } // par défaut
Remarque:
Les arguments, dont la valeur est fournie par défaut, doivent OBLIGATOIREMENT se situer
en fin de liste.
La déclaration suivante est interdite: void f4(char c=2, int n)
{
....;
}
Exercice I-4:
Reprendre lexercice précédent. Par défaut, la fonction puissance devra fournir
x4.
VIII- LA SURDEFINITION DES FONCTIONS
Le C++ autorise la définition de fonctions différentes et portant le même nom. Dans ce
cas, il faut les différencier par le type des arguments.
Exemple (à tester) et exercice I-5:
#include <iostream.h>
#include <conio.h>
void test(int n = 0,float x = 2.5)
{
cout <<"Fonction N°1 : ";
cout << "n= "<<n<<"
x="<<x<<"\n";
}
void test(float x = 4.1,int n = 2)
{
cout <<"Fonction N°2 : ";
cout << "n= "<<n<<"
x="<<x<<"\n";
}
void main()
{
int i = 5; float r = 3.2;
test(i,r); // fonction N°1
test(r,i); // fonction N°2
test(i); // fonction N°1
test(r); // fonction N°2
// les appels suivants, ambigüs, sont rejetés par le compilateur
// test();
// test (i,i);
// test (r,r);
// les inialisations par défaut de x à la valeur 4.1
// et de n à 0 sont inutilisables
getch() ;}
Exemple (à tester) et exercice I-6:
#include <iostream.h>
#include <conio.h>
void essai(float x,char c,int n=0)
{cout<<"Fonction N°1: x = "<<x<<" c =
"<<c<<" n = "<<n<<"\n";}
void essai(float x,int n)
{cout<<"Fonction N°2: x = "<<x<<" n =
"<<n<<"\n";}
void main()
{
char l='z';int u=4;float y = 2.0;
essai(y,l,u); // fonction N°1
essai(y,l); // fonction N°1
essai(y,u); // fonction N°2
essai(u,u); // fonction N°2
essai(u,l); // fonction N°1
// essai(y,y); rejet par le complateur
essai(y,y,u); // fonction N°1
getch() ;}
Exercice I-7:
Ecrire une fonction void affiche (float x, int n = 0) qui affiche xn (avec en particulier
x0 = 1 et donc, 00 = 1).
Ecrire une autre fonction void affiche(int n, float x=0) qui affiche xn (avec en
particulier 0n = 0 et donc, 00 = 0).
Les mettre en oeuvre dans le programme principal, en utilisant la propriété de
surdéfinition.
Remarque: Cet exemple conduit à une erreur de compilation lors dappel de type mn
avec m et n entiers.
IX- LES OPERATEURS new ET delete
Ces deux opérateurs remplacent malloc et free (que lon peut toujours utiliser). Ils
permettent donc de réserver de la place en mémoire, et den libérer.
Exemples: int *ad; // déclaration dun pointeur sur un entier
ad = new int; // réservation de place en mémoire pour un entier
On aurait pu déclarer directement int *ad = new int;
char *adc;
adc = new char[100]; // réservation de place en mémoire pour 100 caractères
On aurait pu déclarer directement char *adc = new char[100];
int *adi;
adi = new int[40]; // réservation de place en mémoire pour 40 entiers
On aurait pu déclarer directement int *adi = new int[40];
delete ad; // libération de place
delete adc;
delete adi;
Exemple (à tester) et exercice I-8:
#include <iostream.h> // new et delete
#include <conio.h> // verifier en testant que cin et cout posent les
// memes pb que scanf et printf (flux d'E-S)
void main()
{
int *ad = new int;
char *adc;
adc = new char[25];
cout<<"Entrer un nombre:";
cin>>*ad;
cout<<"Voici ce nombre:"<<*ad;
cout<<"\nEntrer une phrase:";
cin>>adc;
cout<<"Voici cette phrase:"<<adc;
delete ad;
delete adc;
getch() ;}
Exercice I-9:
Déclarer un tableau de 5 réels. Calculer et afficher leur moyenne.
Remarques:
- Il ne faut pas utiliser conjointement malloc et delete ou bien new et free.
- En TURBO C++, lopérateur new permet de réserver au maximum 64 Koctets en
mémoire; la fonction set_new_handler permet de gérer cette limite.
X- NOTION DE REFERENCE
En C, la notation &n signifie " ladresse de la variable n "
En C++, cette notation possède deux significations:
- Il peut toujours sagir de ladresse de la variable n
- Il peut aussi sagir de la référence à n
Seul le contexte du programme permet de déterminer sil sagit de lune ou
lautre des deux significations.
Exemple: int n;
int &p = n; // p est une référence à n
// p occupe le même emplacement mémoire que n
n = 3;
cout<< p; // laffichage donnera 3
XI -PASSAGE DE PARAMETRE PAR REFERENCE
Rappel:
En C, comme en C++, un sous-programme ne peut modifier la valeur dune variable
locale passée en argument de fonction. Pour se faire, en C, il faut passer ladresse
de la variable.
Exemple (à tester) et exercices I-10 et I-11:
#include <iostream.h> // passage par valeur
#include <conio.h>
void echange(int a,int b)
{
int tampon;
tampon = b; b = a; a = tampon;
cout<<"Pendant l'échange: a = "<<a<<" b =
"<<b<<"\n";
}
void main()
{
int u=5,v=3;
cout<<"Avant echange: u = "<<u<<" v =
"<<v<<"\n";
echange(u,v);
cout<<"Apres echange: u = "<<u<<" v =
"<<v<<"\n";
getch() ;}
Léchange na pas lieu.
#include <iostream.h> // passage par adresse
#include <conio.h>
void echange(int *a,int *b)
{
int tampon;
tampon = *b; *b = *a; *a = tampon;
cout<<"Pendant l'échange: a = "<<*a<<" b =
"<<*b<<"\n";
}
void main()
{
int u=5,v=3;
cout<<"Avant echange: u = "<<u<<" v =
"<<v<<"\n";
echange(&u,&v);
cout<<"Apres echange: u = "<<u<<" v =
"<<v<<"\n";
getch() ;}
Léchange a lieu.
En C++, on préférera le passage par référence:
Exemple (à tester) et exercice I-12:
#include <iostream.h> //passage par référence
#include <conio.h>
void echange(int &a,int &b) // référence à a et b
{
int tampon;
tampon = b; b = a; a = tampon;
cout<<"Pendant l'échange: a = "<<a<<" b =
"<<b<<"\n";
}
void main()
{
int u=5,v=3;
cout<<"Avant echange: u = "<<u<<" v =
"<<v<<"\n";
echange(u,v);
cout<<"Apres echange: u = "<<u<<" v =
"<<v<<"\n";
getch() ;}
Léchange a lieu. Le compilateur prend en charge le passage par adresse si celui-ci
est nécessaire.
Remarquer la simplification de lécriture de la fonction.
XII- CORRIGE DES EXERCICES
Exercice I-3:
#include <iostream.h>
#include <conio.h>
float puissance(float x,int n)
{
float resultat=1;
for(int i=1;i<=n;i++)resultat = resultat * x;
return resultat;
}
void main()
{
char c=5;int i=10,j=6; float r=2.456,r1,r2,r3,r4,r5;
r1 = puissance(r,j);
r2 = puissance(r,c);
r3 = puissance(j,i);
r4 = puissance(j,r);
r5 = puissance(0,4);
cout << "r1 = " <<r1<<"\n";
cout << "r2 = " <<r2<<"\n";
cout << "r3 = " <<r3<<"\n";
cout << "r4 = " <<r4<<"\n";
cout << "r5 = " <<r5<<"\n";
getch() ;}
Exercice I-4:
#include <iostream.h>
#include <conio.h>
float puissance(float x,int n=4)
{
float resultat=1;
for(int i=1;i<=n;i++)resultat = resultat * x;
return resultat;
}
void main()
{
int j=6; float r=2.456,r1,r2,r3,r4,r5;
r1 = puissance(r,j);
r2 = puissance(r);
r3 = puissance(1.4,j);
r4 = puissance(1.4);
cout << "r1 = " <<r1<<"\n";
cout << "r2 = " <<r2<<"\n";
cout << "r3 = " <<r3<<"\n";
cout << "r4 = " <<r4<<"\n";
getch() ;}
Exercice I-7:
#include <iostream.h>
#include <conio.h>
void affiche(float x,int n=0)
{int i = 1;float resultat = 1;
for(;i<=n;i++)resultat = resultat * x;
cout << "x = "<<x<< " n = " << n <<
" resultat = " << resultat <<"\n";}
void affiche(int n,float x=0)
{int i = 1;float resultat = 1;
if (n!=0){for(;i<=n;i++)resultat = resultat * x;}
else (resultat = 0);
cout << "n = "<<n<< " x = " << x <<
" resultat = " << resultat <<"\n";
}
void main()
{
int u=4,v=0;float y = 2.0,z=0;
affiche(u);
affiche(y);
affiche(y,u);
affiche(u,y);
affiche(v,z);
affiche(z,v);
getch() ;}
Exercice I-9:
#include <iostream.h>
#include <conio.h>
void main()
{
float moyenne =0,*tab = new float[5];
int i=0;
for(;i<5;i++)
{
cout<<"Entrer un nombre: ";
cin>>tab[i];
moyenne = moyenne + tab[i];
}
moyenne = moyenne/5;
cout <<"Moyenne = "<<moyenne<<"\n";
delete tab;
getch() ;}