Le sens des deux m'échappe.
Un déclaration introduit un identifiant et décrit son type, qu'il s'agisse d'un type, d'un objet ou d'une fonction. Une déclaration est ce dont le compilateur a besoin pour accepter les références à cet identifiant. Ce sont des déclarations:
extern int bar;
extern int g(int, int);
double f(int, double); // extern can be omitted for function declarations
class foo; // no extern allowed for type declarations
Un définition instancie/implémente effectivement cet identifiant. C'est ce dont l'éditeur de liens a besoin afin de lier des références à ces entités. Ce sont des définitions correspondant aux déclarations ci-dessus:
int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
class foo {};
Une définition peut être utilisée à la place d'une déclaration.
Un identifiant peut être déclaré _ aussi souvent que vous le souhaitez. Ainsi, ce qui suit est légal en C et C++:
double f(int, double);
double f(int, double);
extern double f(int, double); // the same as the two above
extern double f(int, double);
Cependant, il doit être défini exactement une fois. Si vous oubliez de définir quelque chose qui a été déclaré et référencé quelque part, l'éditeur de liens ne sait pas à quoi lier les références et se plaint d'un symbole manquant. Si vous définissez quelque chose plus d'une fois, l'éditeur de liens ne connaît pas lequel des définitions pour lier les références et se plaindre des symboles dupliqués.
Depuis le débat qu'est-ce qu'une classe déclaration vs une classe définition en C++ continue à apparaître (dans les réponses et les commentaires à d'autres questions), je vais coller une citation de la norme C++ ici.
À 3.1/2, C++ 03 dit:
Une déclaration est une définition sauf s'il s'agit [...] d'une déclaration de nom de classe [...].
3.1/3 donne ensuite quelques exemples. Parmi eux:
[Exemple: [...] Struct S {int a; int b; }; // définit S, S :: a et S :: b [...] struct S; // déclare S — end exemple
Pour résumer: La norme C++ considère que struct x;
est un déclaration et struct x {};
un définition _. (En d'autres termes, "déclaration anticipée" un nom impropre}, puisqu'il n'existe aucune autre forme de déclaration de classe en C++.)
Merci à litb (Johannes Schaub) qui a extrait le chapitre et le verset dans une de ses réponses.
A partir de la section 3.1 de la norme C++:
Une déclaration introduit les noms dans une unité de traduction ou redéclare les noms introduits par un fichier .__ précédent. déclarations. Une déclaration spécifie l'interprétation et les attributs de ces noms.
Le paragraphe suivant indique (souligné par moi) qu'une déclaration est une définition sauf si ...
... il déclare une fonction sans spécifier le corps de la fonction
void sqrt(double); // declares sqrt
... il déclare un membre statique dans une définition de classe
struct X
{
int a; // defines a
static int b; // declares b
};
... il déclare un nom de classe
class Y;
... il contient le mot clé extern
sans initialiseur ni corps de fonction
extern const int i = 0; // defines i
extern int j; // declares j
extern "C"
{
void foo(); // declares foo
}
... ou est une déclaration typedef
ou using
.
typedef long LONG_32; // declares LONG_32
using namespace std; // declares std
Maintenant, voici la principale raison pour laquelle il est important de comprendre la différence entre une déclaration et une définition: la règle de définition One. À partir de la section 3.2.1 de la norme C++:
Aucune unité de traduction ne doit contenir plus d'une définition de variable, fonction, type de classe, type d'énumération ou modèle.
Déclaration: "Quelque part, il existe un foo."
Définition: "... et le voici!"
Il existe d’intéressants cas Edge en C++ (certains d’entre eux aussi en C). Considérer
T t;
Cela peut être une définition ou une déclaration, selon le type T
:
typedef void T();
T t; // declaration of function "t"
struct X {
T t; // declaration of function "t".
};
typedef int T;
T t; // definition of object "t".
En C++, lors de l'utilisation de modèles, il existe un autre cas Edge.
template <typename T>
struct X {
static int member; // declaration
};
template<typename T>
int X<T>::member; // definition
template<>
int X<bool>::member; // declaration!
La dernière déclaration était pas une définition. C'est la déclaration d'une spécialisation explicite du membre statique de X<bool>
. Il indique au compilateur: "S'il s'agit d'instancier X<bool>::member
, n'instanciez pas la définition du membre à partir du modèle principal, mais utilisez la définition trouvée ailleurs". Pour en faire une définition, vous devez fournir un initialiseur
template<>
int X<bool>::member = 1; // definition, belongs into a .cpp file.
Déclaration
Les déclarations indiquent au compilateur qu’un L'élément de programme ou le nom existe. UNE déclaration introduit un ou plusieurs noms dans un programme. Les déclarations peuvent se produire plus d'une fois dans un programme . Par conséquent, les classes, les structures, types énumérés, et autres les types définis par l'utilisateur peuvent être déclarés pour chaque unité de compilation.
Définition
Les définitions spécifient quel code ou quelle donnée le nom décrit. Un nom doit être déclarée avant de pouvoir être utilisée.
De la norme C99, 6.7 (5):
Une déclaration spécifie l'interprétation et les attributs d'un ensemble d'identifiants. Un definition d'un identifiant est une déclaration pour cet identifiant qui:
À partir de la norme C++, 3.1 (2):
Une déclaration est un definition sauf si elle déclare une fonction sans spécifier le corps de la fonction, elle contient le spécificateur extern ou une spécification de liaison et ne contient ni initialiseur ni corps de fonction. Elle déclare un membre de données statique dans une déclaration de classe. , c’est une déclaration de nom de classe, ou c’est une déclaration typedef, une déclaration using ou une directive using.
Ensuite, il y a quelques exemples.
Donc curieusement (ou pas, mais cela me surprend un peu), typedef int myint;
est une définition en C99, mais seulement une déclaration en C++.
De wiki.answers.com:
Le terme déclaration signifie (en C) que vous indiquez au compilateur le type, la taille et, en cas de déclaration de fonction, le type et la taille de ses paramètres de variable, ou le type ou la fonction défini par l'utilisateur de votre programme. No l'espace est réservé en mémoire pour toute variable en cas de déclaration. Cependant, le compilateur sait combien d’espace doit être réservé au cas où une variable de ce type serait créée.
par exemple, toutes les déclarations sont les suivantes:
extern int a;
struct _tagExample { int a; int b; };
int myFunc (int a, int b);
La définition, par contre, signifie qu’en plus de tout ce que fait la déclaration, l’espace est également réservé en mémoire. Vous pouvez dire "DEFINITION = DECLARATION + SPACE RESERVATION" en voici des exemples de définition:
int a;
int b = 0;
int myFunc (int a, int b) { return a + b; }
struct _tagExample example;
voir Réponses .
Puisque je ne vois pas de réponse pertinente pour C++ 11, en voici une.
Une déclaration est une definition sauf si elle déclare un/n:
enum X : int;
template<typename T> class MyArray;
int add(int x, int y);
using IntVector = std::vector<int>;
static_assert(sizeof(int) == 4, "Yikes!")
;
Clauses supplémentaires héritées de C++ 03 par la liste ci-dessus:
int add(int x, int y);
extern int a;
ou extern "C" { ... };
class C { static int x; };
struct Point;
typedef int Int;
using std::cout;
using namespace NS;
Un modèle-déclaration est une déclaration. Une déclaration de modèle est également une définition si sa déclaration définit une fonction, une classe ou un membre de données statique.
Exemples tirés de la norme qui différencie déclaration et définition et que j'ai trouvé utiles pour comprendre les nuances qui les séparent:
// except one all these are definitions
int a; // defines a
extern const int c = 1; // defines c
int f(int x) { return x + a; } // defines f and defines x
struct S { int a; int b; }; // defines S, S::a, and S::b
struct X { // defines X
int x; // defines non-static data member x
static int y; // DECLARES static data member y
X(): x(0) { } // defines a constructor of X
};
int X::y = 1; // defines X::y
enum { up , down }; // defines up and down
namespace N { int d; } // defines N and N::d
namespace N1 = N; // defines N1
X anX; // defines anX
// all these are declarations
extern int a; // declares a
extern const int c; // declares c
int f(int); // declares f
struct S; // declares S
typedef int Int; // declares Int
extern X anotherX; // declares anotherX
using N::d; // declares N::d
// specific to C++11 - these are not from the standard
enum X : int; // declares X with int as the underlying type
using IntVector = std::vector<int>; // declares IntVector as an alias to std::vector<int>
static_assert(X::y == 1, "Oops!"); // declares a static_assert which can render the program ill-formed or have no effect like an empty declaration, depending on the result of expr
template <class T> class C; // declares template class C
; // declares nothing
Déclaration:
int a; // this declares the variable 'a' which is of type 'int'
Ainsi, la déclaration associe la variable à un type.
Voici quelques exemples de déclaration.
int a;
float b;
double c;
Maintenant déclaration de fonction:
int fun(int a,int b);
Notez le point-virgule à la fin de la fonction pour indiquer qu'il ne s'agit que d'une déclaration. Le compilateur sait que quelque part dans le programme cette fonction sera définie avec ce prototype. Maintenant, si le compilateur obtient un appel de fonction, quelque chose comme ceci
int b=fun(x,y,z);
Le compilateur générera une erreur en disant qu'il n'y a pas une telle fonction. Parce qu'il n'a pas de prototype pour cette fonction.
Notez la différence entre deux programmes.
Programme 1
#include <stdio.h>
void print(int a)
{
printf("%d",a);
}
main()
{
print(5);
}
Dans ce cas, la fonction d'impression est également déclarée et définie. Puisque l'appel de fonction arrive après la définition. Voir maintenant le programme suivant.
Programme 2
#include <stdio.h>
void print(int a); // In this case this is essential
main()
{
print(5);
}
void print(int a)
{
printf("%d",a);
}
C'est essentiel parce que l'appel de fonction précède la définition, le compilateur doit donc savoir s'il existe une telle fonction. Nous déclarons donc la fonction qui informera le compilateur.
Définition:
Cette partie de la définition d’une fonction s’appelle Définition. Il dit quoi faire dans la fonction.
void print(int a)
{
printf("%d",a);
}
Maintenant avec les variables.
int a; //declaration
a=10; //definition
Parfois, la déclaration et la définition sont regroupées dans une seule déclaration comme celle-ci.
int a=10;
définition signifie fonction réelle écrite et déclaration signifie simple déclaration de fonction .__ pour par ex.
void myfunction(); //this is simple declaration
et
void myfunction()
{
some statement;
}
c'est la définition de la fonction myfunction
Pour comprendre les noms, concentrons-nous d'abord sur les verbes.
déclare -pour annoncer officiellement; proclamer
définir - montrer ou décrire (quelqu'un ou quelque chose) clairement et complètement
Donc, quand vous déclarez quelque chose, vous dites simplement ce que c'est.
// declaration
int sum(int, int);
Cette ligne déclare une fonction C appelée sum
qui prend deux arguments de type int
et renvoie une int
. Cependant, vous ne pouvez pas encore l'utiliser.
Lorsque vous indiquez comment cela fonctionne réellement, vous en définissez la définition.
// definition
int sum(int x, int y)
{
return x + y;
}
Règle de base:
Un déclaration indique au compilateur comment interpréter les données de la variable en mémoire. Ceci est nécessaire pour chaque accès.
Un definition réserve la mémoire pour rendre la variable existante. Cela doit se produire exactement une fois avant le premier accès.
Trouvez des réponses similaires ici: Questions d'entretien d'embauche à C
Un déclaration fournit un nom au programme; un definition fournit une description unique d'une entité (type, instance et fonction, par exemple) dans le programme. Les déclarations peuvent être répétées dans une portée donnée, cela introduit un nom dans une portée donnée.
Une déclaration est une définition sauf si
Une définition est une déclaration sauf si:
Ne pourriez-vous pas affirmer, dans les termes les plus généraux possibles, qu’une déclaration est un identifiant dans lequel aucun stockage n’est alloué et qu’une définition alloue effectivement un stockage à partir d’un identifiant déclaré?
Une idée intéressante - un modèle ne peut pas allouer de stockage tant que la classe ou la fonction n'est pas liée aux informations de type. L'identifiant du modèle est-il une déclaration ou une définition? Il doit s'agir d'une déclaration car aucun stockage n'est alloué et vous ne faites que "prototyper" la classe ou la fonction de modèle.
Pour comprendre la différence entre déclaration et définition, nous devons voir le code d'assemblage:
uint8_t ui8 = 5; | movb $0x5,-0x45(%rbp)
int i = 5; | movl $0x5,-0x3c(%rbp)
uint32_t ui32 = 5; | movl $0x5,-0x38(%rbp)
uint64_t ui64 = 5; | movq $0x5,-0x10(%rbp)
double doub = 5; | movsd 0x328(%rip),%xmm0 # 0x400a20
movsd %xmm0,-0x8(%rbp)
et ce n'est qu'une définition:
ui8 = 5; | movb $0x5,-0x45(%rbp)
i = 5; | movl $0x5,-0x3c(%rbp)
ui32 = 5; | movl $0x5,-0x38(%rbp)
ui64 = 5; | movq $0x5,-0x10(%rbp)
doub = 5; | movsd 0x328(%rip),%xmm0 # 0x400a20
movsd %xmm0,-0x8(%rbp)
Comme vous pouvez le voir, rien ne change.
La déclaration est différente de la définition car elle donne des informations utilisées uniquement par le compilateur. Par exemple, uint8_t indique au compilateur d'utiliser la fonction asm movb.
Regarde ça:
uint def; | no instructions
printf("some stuff..."); | [...] callq 0x400450 <printf@plt>
def=5; | movb $0x5,-0x45(%rbp)
Déclaration n'a pas d'instruction équivalente car ce n'est pas quelque chose à exécuter.
De plus, la déclaration indique au compilateur l'étendue de la variable.
Nous pouvons dire que la déclaration est une information utilisée par le compilateur pour établir l'utilisation correcte de la variable et la durée pendant laquelle de la mémoire appartient à une variable.
Déclaration signifie donner le nom et le type à une variable (dans le cas d'une déclaration de variable) Exemple:
int i;
ou donner le nom, le type de retour et le type de paramètre (s) à une fonction sans corps (en cas de déclaration de fonction)
par exemple:
int max(int, int);
alors que définition signifie assigner une valeur à une variable (dans le cas d'une définition de variable) ..__, par exemple:
i = 20;
ou fournir/ajouter un corps (fonctionnalité) à une fonction est appelée définition de fonction.
par exemple:
int max(int a, int b)
{
if(a>b) return a;
return b;
}
plusieurs déclarations de temps et définition peuvent être faites ensemble comme:
int i=20;
et
int max(int a, int b)
{
if(a>b) return a;
return b;
}
Dans les cas ci-dessus, nous définissons et déclarons la variable i et la fonction max ()
Cela va paraître vraiment ringard, mais c'est la meilleure façon dont j'ai pu garder les termes dans ma tête:
Déclaration: Picture Thomas Jefferson en train de prononcer un discours ... "JE DÉCLARE PAR LA PRÉSENTE QUE CE FOO EXISTE DANS CE CODE SOURCE !!!"
Définition: imaginez un dictionnaire, vous cherchez Foo et ce que cela signifie réellement.
Selon le GNU manuel de la bibliothèque C ( http://www.gnu.org/software/libc/manual/html_node/Header-Files.html )
En C, une déclaration fournit simplement des informations sur l’existence d’une fonction ou d’une variable et donne son type. Pour une déclaration de fonction, des informations sur les types de ses arguments peuvent également être fournies. Le but des déclarations est de permettre au compilateur de traiter correctement les références aux variables et fonctions déclarées. Une définition, en revanche, alloue effectivement le stockage d’une variable ou dit ce que fait une fonction.
Une déclaration présente un nom de symbole au compilateur. Une définition est une déclaration qui alloue de l'espace pour le symbole.
int f(int x); // function declaration (I know f exists)
int f(int x) { return 2*x; } // declaration and definition
Etapes d'une génération exécutable:
(1) pré-processeur -> (2) traducteur/compilateur -> (3) éditeur de liens
À l'étape 2 (traducteur/compilateur), les instructions de déclaration de notre code indiquent au compilateur que nous allons utiliser ces éléments à l'avenir et que vous pourrez trouver la définition plus tard, ce qui signifie
traducteur assurez-vous que: qu'est-ce que c'est? signifie déclaration
et (3) l'étape (l'éditeur de liens) a besoin d'une définition pour lier les choses
Linker assurez-vous que: où est quoi? signifie définition
Il existe des définitions très claires parsemées dans K & R (2e édition); il est utile de les mettre au même endroit et de les lire comme un seul:
"Définition" fait référence à l'endroit où la variable est créée ou à laquelle un stockage est attribué; "déclaration" fait référence aux endroits où la nature de la variable est indiquée mais où aucun stockage n'est alloué. [p. 33]
...
Il est important de distinguer entre la déclaration d'une variable externe et sa définition. Une déclaration annonce les propriétés d'une variable (principalement son type); une définition entraîne également la mise de côté du stockage. Si les lignes
int sp; double val[MAXVAL]
apparaissent en dehors de toute fonction, elles définissent les variables externes
sp
etval
, provoquent l’annulation du stockage et servent également de déclaration pour le reste du fichier source .D'autre part, les lignes
extern int sp; extern double val[];
declare pour le reste du fichier source que
sp
est unint
et queval
est un tableaudouble
(dont la taille est déterminée ailleurs) , mais ils ne créent pas les variables ou ne leur réservent pas de stockage.Il ne doit exister qu'un seul définition d'une variable externe parmi tous les fichiers composant le programme source. ... Les tailles de tableau doivent être spécifiées avec la définition, mais sont facultatives avec une déclaration
extern
. [pp. 80-81]...
Les déclarations spécifient l'interprétation donnée à chaque identifiant; ils ne réservent pas nécessairement le stockage associé à l'identifiant. Les déclarations qui réservent le stockage sont appelées définitions. [p. 210]
Mon exemple préféré est "int Num = 5" ici votre variable est 1. définie comme int 2. déclarée comme Num et 3. instanciée avec la valeur cinq nous
Une classe ou une structure vous permet de modifier la manière dont les objets seront définis lorsqu’il sera utilisé ultérieurement. Par exemple
Lorsque nous apprenons à programmer, ces deux termes sont souvent confondus parce que nous faisons souvent les deux en même temps.
Le concept de déclaration et de définition constituera un écueil lorsque vous utiliserez la classe de stockage externe car votre définition sera à un autre emplacement et vous déclarez la variable dans votre fichier de code local (page). Une différence entre C et C++ est que dans C vous les déclarations sont faites normalement au début d'une page de fonction ou de code. En C++, ce n'est pas comme ça. Vous pouvez déclarer à un endroit de votre choix.