OVH Cloud OVH Cloud

débutant

2 réponses
Avatar
jmarc
je vois dans le livre que j'ai acheté
d'écrire : using namespace std;

que std est un espace de noms
quest ce qu'un espace de nom
si je ne précise pas cette ligne alors je devrais écrire comme en C :
#include <iostream.h>?
merci

2 réponses

Avatar
Loïc Joly
jmarc wrote:

je vois dans le livre que j'ai acheté
d'écrire : using namespace std;

que std est un espace de noms
quest ce qu'un espace de nom


Je pense que ton livre doit t'expliquer plus tard ce que ça signifie,
mais il n'est pas possible de tout explique d'un coup. L'idée des
espaces de noms est d'éviter d'avoir des conflits entre des noms de deux
bibliothèques différentes. On préfixe alors le nom de chaque élément
d'une bibliothèque par un préfixe, suivi de ::. Le préfixe choisi pour
la bilbiothèque standard est std. Par exemple std::cout.

Utiliser using namespace std; consiste à dire au compilateur : Je sais
que dans mon cas, il n'y aura pas de conflits, alors je ne veux pas
avoir à répéter ce préfixe.

C'est d'ailleur pourquoi il ne faut pas mettre using namespace XXX; dans
un fichier d'en-tête, puisqu'on ne peut pas savoir dans quel contexte ce
fichier d'en-tête sera utilisé.

si je ne précise pas cette ligne alors je devrais écrire comme en C :
#include <iostream.h>?


Ceci n'est pas du C. C'est du vieux C++, d'avant que le C++ soit
normalisé. Ce qui veux dire entre autre qu'il peut y avoir des
différences selon les compilateurs, voire qu'un compilateur peut choisir
de ne pas le fournir.

--
Loïc

Avatar
James Kanze
"jmarc" writes:

|> je vois dans le livre que j'ai acheté
|> d'écrire : using namespace std;

|> que std est un espace de noms
|> quest ce qu'un espace de nom

Je crois que le vocable exact est un espace référentiel ; j'ai aussi
entendu souvent espace de nommage. C'est simplement une encapsulation de
plus, pour donner facilement des noms plus longs (avec un préfix) à tout
ce qui s'y trouve, et éventuellement, et préciser qu'on aimerait éviter
les noms plus longs, parce qu'on sait il n'y peut pas y avoir
d'ambiguïté. (C'est aussi un truc pour compliquer la résolution du
surchage encore plus, mais c'est une autre histoire. Pas pour des
débutants.)

En l'occurrance, on a mis toute la bibliothèque standard dans l'espace
référenciel std. Les sorties standard ne s'appelle donc pas cout, mais
std::cout. Et on a la possibilité de dire qu'on veut que cout signifie
toujours std::cout :
using std::cout ;
On peut aussi dire simplement qu'on veut utiliser tous les noms de la
bibliothèque standard de cette façon, au moyen de :
using namespace std ;
À mon avis (et ça n'engage que moi), on peut raisonablement prendre deux
politiques (ou plutôt deux et démi) : on peut simplement vouloir faire
comme on a toujours fait, en ignorant les espaces référentiels. Dans ce
cas-là, on pourrait ou bien considérer que le nom des sorties standard
est std::cout, avec des caractères un peu drôle (des ':'), ou on
pourrait légitimement faire un « using namespace std ; » en tête, et
considérer que les noms ne sont pas changés. (Personellement, j'ai
choisi la première solution, mais en partie parce que je connais très
bien la bibliothèque classique préstandard, et je veux bien visualiser
que ce n'est pas le cout que je connais que j'utilise.) Sinon, on peut
décider de jouer le jeu des espaces référentiels au fond, et mettre tout
ce qu'on écrit soi-même dans un espace référentiel aussi.

Entre les deux solutions, c'est sans doute la seconde qui doit prévaloir
à la longue, au moins pour les grands projets -- les espaces
référentiels jouent un rôle dans la résolution des surcharges, par
exemple. Pour les plus petits projets, et surtout pour des projets de
débuttant, c'est moins sûr. Et actuellement, il faut aussi faire gaffe
aux problèmes de portabilité ; j'avais récemment réécrit ma bibliothèque
pour qu'elle utilise des espaces référentiels, seulement pour revenir en
arrière et les supprimer à cause des problèmes avec certains
compilateurs, surtout VC++ 6.0 (mais j'ai aussi eu de petits problèmes
avec Sun CC). En revanche, on en a fait une utilisation à fond sur mon
dernier projet, où la portabilité ne jouait pas de rôle, et où on
s'était fixé sur un seul compilateur, g++ 2.95.2.

|> si je ne précise pas cette ligne alors je devrais écrire comme en C :
|> #include <iostream.h>?

Comme en C ? :-)

Je crois que tu es en train de mélanger deux choses distinctes. (Mais ne
t'en fais pas -- il y a des fournisseurs de compilateurs qui n'arrivent
pas à les tenir à part non plus.) La norme C++ n'est apparue qu'en 1998,
or qu'on se servait de C++ depuis bien avant. (Je me suis servi la
première fois dans une grande application professionnelle en 1992.) Et
évidemment, on n'a pas attendu la norme pour avoir un pseudo-standard
pour ce qui concerne les entrées/sorties. Or, plutôt que d'agréer la
norme de facto existante, le comité C++ a inventé quelque chose de
complètement nouvelle, avec seulement un rapport attenué avec
l'existant. (Il faut dire qu'au moins en partie, il n'avait pas le
choix -- depuis la fin des années 1980, il est devenu quasiment
impossible à promoluguer une norme de langage sans qu'on supporte des
caractères étendus en entrée/sortie.)

En principe, alors, <iostream.h> te donne les flux classiques, et
<iostream>, <ostream>, <istream>... les flux standard. Aussi en
principe, les flux classiques se trouvent dans l'espace référentiel
global, et les flux standard dans std::. Dans la pratique, c'est encore
plus compliqué -- ce que je viens de dire vaut pour VC++ (au moins
version 6.0), mais les anciennes versions de g++ ont un <iostream> (mais
pas de <ostream>, etc.) qui en fait incorpore les flux classiques (et le
compilateur traite std comme un synonyme pour l'espace référentiel
global), tandis que les versions plus récente de g++ ou de Sun CC ont un
<iostream.h> qui incorpore les flux standard, mais les mettent dans
l'espace global.

Mais si tu es en train d'apprendre le C++ aujourd'hui, et que tu n'as
pas de code existant, avec lequel il faut être compatible, la solution
est simple : procure-toi un compilateur qui supporte les flux standard
(c'est le cas de toutes les versions récentes des compilateurs que je
connais), et limite-toi à eux. Ce qui veut dire :

- Le nom des types, des flux, etc., commence toujours par std::. Si tu
n'as pas envie d'écrire des std:: partout, dans les petites
applications, tu peux te permettre un « using namespace std ; » en
tête de *ton* code (jamais dans un en-tête, ou quelque part où tu
l'imposerais aux autres).

- Les définitions dont tu auras besoin sont réparti dans plusieurs
fichiers. Donc, <iostream> ne définit que les flux standard, mais
pas les opérations sur des flux, <ostream> définit des opérations de
sortie, et <istream> des opérations d'entrée. Dans les vraies
applications, c'est assez rare qu'on a besoin d'un flux standard et
d'une opération sur un flux dans la même source, mais dans les
petits programmes d'apprentissage, il faut prèsque toujours inclure
au moins <iostream> et <ostream>, et parfois aussi <istream>.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34