
Envoyé par
deubelte
Qu'est ce que l'utilisation directive?
Il ne s'agit pas d'un "utilisation directive", mais de l'utilisation d'une directive 
using et namespace sont deux mots clés, qui, mis bout à bout représentent une directive (une instruction) indiquant au compilateur qu'il doit considérer l'espace de noms indiqué comme s'il faisait partie intégrante de l'espace de nom global, afin de permettre l'utilisation de cout plutôt que std::cout (par exemple)
Il faut éviter cette directive dans les fichiers d'en-tête pour la simple et bonne raison qu'elle se propage du fait du jeu des inclusions en cascade dans tous les fichiers qui incluent (même de manière indirecte) le fichier d'en-tête dans lequel elle est utilisée, ce qui fait perdre tout l'intérêt des espaces de nom 
oui, ici:
1 2 3 4 5 6 7 8
| #ifndef HEADER_H
#define HEADER_H
#pragma once
#include <vector>
#include <stdlib.h>
#include <stdio.h>
using namespace std; |
dane le deuxième code que tu donne et ici dans le code que tu donne dans la question (s'il s'agit du code d'un fichier d'en-tête)
1 2 3 4 5 6
| #pragma once
#include <vector>
#include <stdlib.h>
#include <stdio.h>
using namespace std; |
Il vaut mieux utiliser std::cout que
1)using namespace std;
2)puis cout.
Dans les fichier d'en-tête (*.h, *.hpp,...) oui, dans les fichier d'implémentation (*.cpp), c'est moins grave 
Dans le code que tu donnes dans la question
déclare un espace de noms anonyme 
Je sais, mais il ne me semble pas avoir utilisé des variables globales.
il ne faut pas confondre espace de noms et structure ou classe...
toutes les variables déclarées dans l'espace de noms Donnees dans le code
1 2 3 4 5 6 7 8 9 10
| namespace Donnees{
double H;
long nb_point;
const long N=10000;
double Gamma_a;
double Gamma_b;
double Gamma_c;
double Gamma_c_b;
vector<double> temps;
} |
deviennent des variables globales, même si, du fait qu'elles appartiennent à l'espace de noms Données, il faut y accéder en préfixant leur nom de Donnees::
Une variable globale est une variable déclarée en dehors de toute structure ou de toute fonction...
Un espace de noms ne représente qu'un chemin permettant de lever l'ambigüité lorsque tu te trouve face à une situation dans laquelle deux types (ou deux fonction) différent(e)s devraient porter des noms identiques
Mais sans vouloir être impoli, je n'ai pas eu de réponse à ma question. Je rame toujours dessus.
Maintenant que nous avons le fichier "header.h" complet, nous allons pouvoir te répondre 
Soit tu modifie le code de manière à ce que Donnees soit une structure (class ou struct), soit tu déclares les variables "extern" dans le fichier d'en-tête et tu les définis dans un fichier d'implémentation séparé.
Pour que cette réponse "courte" soit compréhensible, il faut peut être revenir sur deux termes génériques:
La déclaration de (le fait de déclarer) quelque chose consiste simplement à dire au compilateur que ce quelque chose existe.
La définition de (le fait de définir) quelque chose consiste à donner au compilateur le "corps" de ce quelque chose.
pour une fonction, nous avons donc
void foo(/*paramètres éventuels */);
qui est la déclaration de la fonction et
1 2 3 4
| void foo(/*paramètres éventuels */)
{
/*ce qui doit être fait */
} |
qui est la définition de la fonction.
Pour une classe ou une structure, nous avons
1 2 3
| class MyClass;
/* ou */
struc MyStruct; |
qui est la déclaration de la classe ou de la structure et
1 2 3 4 5 6 7 8 9
| class MyClass
{
/*contenu de MyClass */
};
/* ou */
struct MyStruct
{
/* contenu de MyStruct */
}; |
qui est la définition de la structure
En C++, il faut suivre le principe du "One Definition Rule", c'est à dire qu'une chose ne peut être définie qu'une et une seule fois dans le code.
Pour les fonctions, classes et structures, le simple ajout de "garde anti inclusion multiple" du genre de
1 2 3 4 5 6 7
| #ifndef UN_TERME_UNIQUE
#define UN_TERME_UNIQUE
/* définition des classes et structures,
* déclaration des fonctions
* définition de fonctions inline
*/
#endif |
permet de s'assurer que nous suivrons cette règle de la définition unique.
La raison est simple: nous donnons un corps au type, mais nous ne demandons pas encore de réserver de l'espace mémoire pour pouvoir l'utiliser
Par contre, pour les variables globales, il en va autrement 
Le problème, c'est que lorsque tu déclare une variable (qui n'est pas un pointeur ou une référence), la déclaration est aussi... la définition: le fait de déclarer une variable implique de manière automatique la réservation d'un espace mémoire suffisant pour... contenir les informations transportées par cette variable
Comme la déclaration et la définition d'une variable ne font qu'un, il faut:
- s'assurer que la définition ne sera effectuée qu'une fois
- demander au compilateur de simplement prendre en compte que la variable que nous déclarons (pour qu'il sache qu'elle existe) est définie "autre part", et qu'il pourra y accéder en temps utiles
Il faut donc définir, dans un fichier *.cpp la variable globale sous la forme de
1 2 3 4 5 6 7 8 9 10
| namespace Donnees{
double H =valeurDeHInitiale;
long nb_point = valeurDen_pointInitiale;
const long N=10000;
double Gamma_a = valeurDeGamma_aInitiale;
double Gamma_b = valeurDeGamma_bInitiale;
double Gamma_c = valeurDeGamma_cInitiale;
double Gamma_c_b = valeurDeGamma_c_bInitiale;
vector<double> temps;
} |
et préciser dans le fichier d'en-tête que la variable existe "autre part" en préfixant la déclaration du mot clé extern sous la forme de
1 2 3 4 5 6 7 8 9 10
| namespace Donnees{
extern double H;
extern long nb_point;
extern const long N;
extern double Gamma_a;
extern double Gamma_b;
extern double Gamma_c;
extern double Gamma_c_b;
extern vector<double> temps;
} |
NOTA: Les explications qui précèdent sont simplifiées de manière à te donner une idée du principe... Elles n'ont donc pas la prétention d'être complètes, ni celle d'utiliser les termes réellement appropriés
(mais ma réponse est déjà largement assez longue
)
Partager