Quelle est la différence entre une définition et une déclaration?

La signification des deux m’échappe.

Une déclaration introduit un identifiant et décrit son type, que ce soit un type, un object ou une fonction. Une déclaration est ce que le compilateur doit accepter des 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 

Une définition instancie / implémente effectivement cet identifiant. C’est ce que l’éditeur de liens a besoin pour relier les 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, alors l’éditeur de liens ne sait pas à quoi lier les références et se plaint des symboles manquants. Si vous définissez quelque chose plus d’une fois, l’éditeur de liens ne sait pas laquelle des définitions pour lier les références à des symboles dupliqués.


Puisque le débat sur ce qu’est une déclaration de classe par rapport à une définition de classe en C ++ ne cesse de surgir (dans les réponses et les commentaires aux autres questions), je collerai une citation du standard C ++ ici.
A 3.1 / 2, C ++ 03 dit:

Une déclaration est une définition à moins qu’elle ne soit une déclaration de nom de classe […].

3.1 / 3 donne alors quelques exemples. Parmi eux:

 [Exemple: [...]
 struct S {int a;  int b;  };  // définit S, S :: a et S :: b [...]
 struct S;  // déclare S
 —Exemple

Pour résumer: le standard C ++ considère struct x; être une déclaration et struct x {}; une définition . (En d’autres termes, “faire une déclaration” est un abus de langage , car il n’existe pas d’autres formes de déclaration de classe en C ++.)

Merci à Litb (Johannes Schaub) qui a creusé le chapitre et le vers dans l’une de ses réponses.

De la section standard C ++ 3.1:

Une déclaration introduit des noms dans une unité de traduction ou redéfinit les noms introduits par les déclarations précédentes. Une déclaration spécifie l’interprétation et les atsortingbuts de ces noms.

Le paragraphe suivant indique (souligne le mien) qu’une déclaration est une définition à moins que …

… 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 un typedef ou une instruction using .

 typedef long LONG_32; // declares LONG_32 using namespace std; // declares std 

Maintenant, la raison principale pour laquelle il est important de comprendre la différence entre une déclaration et une définition: la règle à une définition . A partir de la section 3.2.1 du standard C ++:

Aucune unité de traduction ne doit contenir plus d’une définition d’une variable, d’une fonction, d’un type de classe, d’un type d’énumération ou d’un modèle.

Déclaration: “Quelque part, il existe un foo.”

Définition: “… et voilà!”

Il y a des cas intéressants en C ++ (certains en C aussi). 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 y a un autre cas d’arête.

 template  struct X { static int member; // declaration }; template int X::member; // definition template<> int X::member; // declaration! 

La dernière déclaration n’était pas une définition. C’est la déclaration d’une spécialisation explicite du membre statique de X . Il indique au compilateur: “S’il s’agit d’instancier X::member , n’instanciez pas la définition du membre à partir du modèle primaire, mais utilisez la définition trouvée ailleurs”. Pour en faire une définition, vous devez fournir un initialiseur

 template<> int X::member = 1; // definition, belongs into a .cpp file. 

Déclaration

Les déclarations indiquent au compilateur qu’un élément de programme ou un nom existe. Une déclaration introduit un ou plusieurs noms dans un programme. Les déclarations peuvent se produire plusieurs fois dans un programme. Par conséquent, les classes, structures, types énumérés et autres types définis par l’utilisateur peuvent être déclarés pour chaque unité de compilation.

Définition

Les définitions spécifient le code ou les données que le nom décrit. Un nom doit être déclaré avant de pouvoir être utilisé.

De la norme C99, 6.7 (5):

Une déclaration spécifie l’interprétation et les atsortingbuts d’un ensemble d’identifiants. Une définition d’identifiant est une déclaration pour cet identifiant qui:

  • pour un object, le stockage est réservé pour cet object;
  • pour une fonction, comprend le corps de la fonction;
  • pour une constante d’énumération ou un nom typedef, est la (seule) déclaration de l’identifiant.

A partir du standard C ++, 3.1 (2):

Une déclaration est une définition à moins de déclarer une fonction sans spécifier le corps de la fonction, elle contient le spécificateur externe ou une spécification de liaison et ni un initialiseur ni un corps de fonction, elle déclare un membre de données statique dans une déclaration de classe. déclaration de nom de classe ou déclaration de type typedef, déclaration-using ou directive using.

Ensuite, il y a quelques exemples.

Donc intéressant (ou pas, mais je suis un peu surpris par cela), typedef int myint; est une définition en C99, mais uniquement 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 parameters pour toute variable ou le type ou la fonction défini par l’utilisateur dans votre programme. Aucun espace n’est réservé en mémoire pour une variable en cas de déclaration. Cependant, le compilateur sait combien d’espace il faut réserver si une variable de ce type est créée.

Par exemple, voici toutes les déclarations:

 extern int a; struct _tagExample { int a; int b; }; int myFunc (int a, int b); 

La définition, quant à elle, signifie que dans les ajouts à tout ce que fait la déclaration, l’espace est également réservé en mémoire. Vous pouvez dire “DEFINITION = DECLARATION + SPACE RESERVATION” ci-dessous sont des exemples de définition:

 int a; int b = 0; int myFunc (int a, int b) { return a + b; } struct _tagExample example; 

voir les réponses

C ++ 11 Update

Comme je ne vois pas de réponse pertinente pour C ++ 11, voici une réponse.

Une déclaration est une définition sauf si elle déclare a / n:

  • énumération opaque enum enum X : int;
  • paramètre template – T dans le template class MyArray;
  • déclaration de paramètre – x et y dans int add(int x, int y);
  • déclaration d’alias – en using IntVector = std::vector;
  • déclaration d’assert statique – static_assert(sizeof(int) == 4, "Yikes!")
  • déclaration d’atsortingbut (définie par l’implémentation)
  • déclaration vide ;

Les clauses supplémentaires héritées de C ++ 03 par la liste ci-dessus:

  • déclaration de fonction – add in int add(int x, int y);
  • spécificateur externe contenant une déclaration ou un spécificateur de liaison – extern int a; ou extern "C" { ... };
  • membre de données statique dans une classe – x dans la class C { static int x; }; class C { static int x; };
  • class / struct declaration – struct Point;
  • déclaration typedef – typedef int Int;
  • en utilisant la déclaration – en using std::cout;
  • using directive – en 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.

Des exemples de la norme qui différencie la déclaration et la définition que j’ai trouvé utile pour comprendre les nuances entre eux:

 // 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; // declares IntVector as an alias to std::vector 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 C; // declares template class C ; // declares nothing 

définition signifie que la fonction réelle écrite et la déclaration signifient une simple fonction de déclaration pour, par exemple,

 void myfunction(); //this is simple declaration 

et

 void myfunction() { some statement; } 

c’est la définition de la fonction myfunction

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 ça

 int b=fun(x,y,z); 

Le compilateur émettra une erreur en disant qu’il n’y a pas de telle fonction. Parce qu’il n’a pas de prototype pour cette fonction.

Notez la différence entre deux programmes.

Programme 1

 #include  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. Depuis l’appel de fonction vient après la définition. Maintenant, voyez le programme suivant.

Programme 2

  #include  void print(int a); // In this case this is essential main() { print(5); } void print(int a) { printf("%d",a); } 

Il est essentiel car l’appel de la 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 à l’intérieur de 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; 

Règle générale:

  • Une déclaration indique au compilateur comment interpréter les données de la variable en mémoire. Ceci est nécessaire pour chaque access.

  • Une définition réserve la mémoire pour rendre la variable existante. Cela doit arriver exactement une fois avant le premier access.

Ne pourriez-vous pas dire, 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 réellement le stockage à partir d’un identifiant déclaré?

Une pensé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. Ainsi, l’identificateur de modèle est-il une déclaration ou une définition? Ce devrait être une déclaration car aucun stockage n’est alloué et vous ne faites que «prototyper» la classe ou la fonction du modèle.

Trouvez des réponses similaires ici: Questions d’entretien technique en C

Une déclaration fournit un nom au programme; une définition fournit une description unique d’une entité (par exemple, type, instance et fonction) dans le programme. Les déclarations peuvent être répétées dans un domaine donné, il introduit un nom dans un domaine donné.

Une déclaration est une définition à moins que

  • La déclaration déclare une fonction sans spécifier son corps,
  • Déclaration contient un spécificateur externe et aucun initialiseur ou corps de fonction,
  • Déclaration est la déclaration d’un membre de données de classe statique sans définition de classe,
  • La déclaration est une définition de nom de classe,

Une définition est une déclaration à moins que:

  • La définition définit un membre de données de classe statique,
  • La définition définit une fonction membre non intégrée.

Déclaration signifie donner un nom et un type à une variable (en cas de déclaration de variable), par exemple:

  int i; 

ou donner le nom, le type de retour et le type de paramètre à une fonction sans corps (en cas de déclaration de fonction)

par exemple:

 int max(int, int); 

alors que la définition signifie affecter une valeur à une variable (en cas de définition de variable). par exemple:

 i = 20; 

ou fournir / append 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éfinitions peuvent être faites ensemble comme suit:

 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 de garder les termes dans ma tête:

Déclaration: Image de Thomas Jefferson prononçant un discours … “JE DÉCLARE QUE CE FOIS EXISTE DANS CE CODE SOURCE !!!”

Définition: imaginez un dictionnaire, vous cherchez Foo et ce que cela signifie réellement.

Pour comprendre la différence entre la déclaration et la 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 que la 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 ne pouvez rien voir changer.

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 dit au compilateur d’utiliser la fonction asm movb.

Regarde ça:

 uint def; | no instructions printf("some stuff..."); | [...] callq 0x400450  def=5; | movb $0x5,-0x45(%rbp) 

La déclaration n’a pas d’instructions équivalentes car ce n’est pas quelque chose à exécuter.

De plus, la déclaration indique au compilateur la scope 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 pour combien de temps la mémoire appartient à certaines variables.

Pour comprendre les noms, concentrons-nous d’abord sur les verbes.

déclarer – 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 retourne un int . Cependant, vous ne pouvez pas encore l’utiliser.

Lorsque vous fournissez comment cela fonctionne réellement , c’est la définition de cela.

 // definition int sum(int x, int y) { return x + y; } 

Selon le manuel de la bibliothèque GNU C ( http://www.gnu.org/software/libc/manual/html_node/Header-Files.html )

En C, une déclaration fournit simplement des informations indiquant qu’une fonction ou une variable existe 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, quant à elle, alloue effectivement le stockage d’une variable ou indique ce que fait une fonction.

Une déclaration introduit un nom dans le programme; une définition fournit une description unique d’une entité (par exemple, type, instance et fonction). Les déclarations peuvent être répétées dans un domaine donné, il introduit un nom dans un domaine donné. Il doit y avoir exactement une définition de chaque object, fonction ou classe utilisée dans un programme C ++. Une déclaration est une définition sauf si:

 * it declares a function without specifying its body, * it contains an extern specifier and no initializer or function body, * it is the declaration of a static class data member without a class definition, * it is a class name definition, * it is a typedef declaration. 

Une définition est une déclaration à moins que:

 * it defines a static class data member, * it defines a non-inline member function. 

Différence entre déclarer et définir avec des fonctions: L’énoncé prototype d’une fonction le déclare, c’est-à-dire indique au compilateur la fonction – son nom, son type de retour et son nombre et type de parameters. L’en-tête de la fonction, suivi du corps de la fonction, définit la fonction – donnant les détails des étapes à suivre pour effectuer l’opération de la fonction.

Ex.

Code:

 //Declare int foo(int); //Define int foo(int){ ... } 

En ce qui concerne les variables: Pour les variables automatiques et de registre, il n’y a pas de différence entre la définition et la déclaration. Le processus de déclaration d’une variable automatique ou d’une variable de registre définit le nom de la variable et alloue la mémoire appropriée.

Cependant, pour les variables externes: Parce que la mémoire pour une variable doit être allouée une seule fois, pour garantir que l’access à la variable fait toujours référence à la même cellule. toutes les variables doivent être définies une seule fois.

Si une variable externe doit être utilisée dans un fichier autre que celui dans lequel elle est définie, un mécanisme est nécessaire pour “connecter” une telle utilisation avec la cellule de variable externe définie de manière unique qui lui est atsortingbuée. Ce processus de connexion des références de la même variable externe dans des fichiers différents est appelé résolution des références.

Il peut être défini et déclaré avec une déclaration en dehors de toute fonction, sans spécificateur de classe de stockage. Une telle déclaration alloue de la mémoire pour la variable. Une déclaration peut également être utilisée pour déclarer simplement un nom de variable avec le spécificateur de classe de stockage externe au début de la déclaration. Une telle déclaration spécifie que la variable est définie ailleurs, c’est-à-dire que la mémoire de cette variable est allouée dans un autre fichier. Ainsi, l’access à une variable externe dans un fichier autre que celui dans lequel il est défini est possible s’il est déclaré avec le mot-clé extern; aucune nouvelle mémoire n’est allouée. Une telle déclaration indique au compilateur que la variable est définie ailleurs et que le code est compilé avec la variable externe laissée non résolue. La référence à la variable externe est résolue lors du processus de liaison.

Ex.

Code

 //file1.c extern char stack[10]; extern int stkptr; .... //file2.c char stack[10]; int stkptr; .... 

Ces déclarations indiquent au compilateur que les variables stack [] et stkptr sont définies ailleurs, généralement dans un autre fichier. Si le mot-clé extern était omis, les variables seraient considérées comme nouvelles et la mémoire leur serait atsortingbuée. N’oubliez pas que l’access à la même variable externe définie dans un autre fichier n’est possible que si le mot clé extern est utilisé dans la déclaration.

Le concept de déclaration et de définition constituera un piège lorsque vous utiliserez la classe de stockage externe car votre définition sera dans un autre emplacement et vous déclarerez 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 fonction ou d’une page de code. En C ++, ce n’est pas comme ça. Vous pouvez déclarer à un endroit de votre choix.

My favorite example is “int Num = 5” here your variable is 1. defined as int 2. declared as Num and 3. instantiated with a value of five. nous

  • Define the type of an object, which may be built-in or a class or struct.
  • Declare the name of an object, so anything with a name has been declared which includes Variables, Funtions, etc.

A class or struct allows you to change how objects will be defined when it is later used. Par exemple

  • One may declare a heterogeneous variable or array which are not specifically defined.
  • Using an offset in C++ you may define an object which does not have a declared name.

When we learn programming these two terms are often confused because we often do both at the same time.

A declaration presents a symbol name to the comstackr. A definition is a declaration that allocates space for the symbol.

 int f(int x); // function declaration (I know f exists) int f(int x) { return 2*x; } // declaration and definition 

A variable is declared when the comstackr is informed that a variable exists (and this is its type); it does not allocate the storage for the variable at that point.

A variable is defined when the comstackr allocates the storage for the variable.

Whenever we write function after the main function, comstackr will through the error since it does not have any idea about the function at the time of calling function. If we provide prototype declaration of function then we comstackr will not look for the definition.

 int sum(int,int); main() { int res = sum(10,20); } int sum(int n1,int n2) { return(n1+n2); } 

In the above example , first line is called as function declaration.

 int sum(int,int); 

Declaring Variable

Whenever we write declaration statement then memory will not be allocated for the variable. Variable declaration will randomly specify the memory location.

 int ivar; float fvar; 

Variable Declaration Vs Definition Differentiation Parameters

A. Space Reservation :

Whenever we declare a variable then space will not be reserved for the variable. Whenever we declare a variable then comstackr will not look for other details such as definition of the variable.

Declaration is handy way to write code in which actual memory is not allocated.

 struct book { int pages; float price; char *bname; }; 

In the above declaration memory is not allocated. Whenever we define a variable then memory will be allocated for the variable.

 struct book b1; 

B. What it does ?

  1. Declaration will identify the data type of the identifier.
  2. Definition of the variable will assign some value to it.

As the stages of a compilation

(1) per-processor -> (2) translator -> (3) assembler -> (4) linker

before going to (2) stage (translator/comstackr), declaration statements in our code trying to tell to the (2) stage that this things we are going to use in future and you can find definition later, meaning is :

translator make sure that : what is what ? means declaration

and (4) stage (linker) needs definition to bind the things

Linker make sure that : where is what ? means definition