it-swarm.com.de

Was ist der Unterschied zwischen einer Definition und einer Deklaration?

Die Bedeutung von beiden entzieht sich mir.

769
Maciek

Ein Deklaration führt einen Bezeichner ein und beschreibt seinen Typ, sei es Typ, Objekt oder Funktion. Eine Deklaration lautet was der Compiler benötigt, um Verweise auf diesen Bezeichner zu akzeptieren. Dies sind Deklarationen: 

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

Ein definition instantiiert/implementiert diese Kennung. Es ist was der Linker benötigt, um Verweise auf diese Entitäten zu verlinken. Dies sind Definitionen, die den obigen Deklarationen entsprechen: 

int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
class foo {};

Anstelle einer Deklaration kann eine Definition verwendet werden. 

Ein Bezeichner kann deklariert beliebig oft sein. Daher ist Folgendes in C und C++ zulässig: 

double f(int, double);
double f(int, double);
extern double f(int, double); // the same as the two above
extern double f(int, double);

Es muss jedoch genau einmal definiert sein. Wenn Sie vergessen, etwas zu definieren, das irgendwo deklariert und referenziert wurde, weiß der Linker nicht, worauf er Verweise verlinken soll, und er beschwert sich über fehlende Symbole. Wenn Sie etwas mehr als einmal definieren, kennt der Linker which der Definitionen nicht, um Verweise zu verknüpfen und sich über duplizierte Symbole zu beschweren. 


Da in der Debatte, was eine Klasse Deklaration gegen eine Klasse Definition in C++ ist, immer wieder auftaucht (in Antworten und Kommentaren zu anderen Fragen), werde ich ein Zitat aus dem C++ - Standard einfügen Hier.
C++ 03 zu 3.1/2 sagt:

Eine Deklaration ist eine Definition, es sei denn, es handelt sich [...] um eine Klassenname-Deklaration [...].

3.1/3 gibt dann einige Beispiele. Unter ihnen:

 [Beispiel: [...] 
 Struct S {int a; int b; }; // definiert S, S :: a und S :: b [...] 
 struct S; // deklariert S 
— Ende Beispiel 

Um es zusammenzufassen: Der C++ - Standard betrachtet struct x; als Deklaration und struct x {}; a Definition. (Mit anderen Worten, "Vorwärtsdeklaration" eine Fehlbezeichnung, da in C++ keine anderen Klassendeklarationen vorhanden sind.) 

Dank an litb (Johannes Schaub) , der das eigentliche Kapitel und den Vers in einer seiner Antworten ausgegraben hat. 

782
sbi

Aus dem C++ - Standardabschnitt 3.1:

Eine Deklaration fügt Namen in eine Übersetzungseinheit ein oder deklariert Namen, die durch vorherige .__ eingeführt wurden. Erklärungen. Eine Deklaration legt die Interpretation und Attribute dieser Namen fest.

Der nächste Absatz besagt (mein Schwerpunkt), dass eine Erklärung eine Definition ist es sei denn ...

... deklariert eine Funktion, ohne den Körper der Funktion anzugeben

void sqrt(double);  // declares sqrt

... deklariert einen statischen Member innerhalb einer Klassendefinition

struct X
{
    int a;         // defines a
    static int b;  // declares b
};

... es gibt einen Klassennamen an

class Y;

... enthält das Schlüsselwort extern ohne einen Initialisierer oder einen Funktionskörper

extern const int i = 0;  // defines i
extern int j;  // declares j
extern "C"
{
    void foo();  // declares foo
}

... oder ist eine typedef- oder using-Anweisung.

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

Nun, aus dem großen Grund, warum es wichtig ist, den Unterschied zwischen Deklaration und Definition zu verstehen: Die One Definition Rule . Aus Abschnitt 3.2.1 des C++ - Standards:

Keine Übersetzungseinheit darf mehr als eine Definition einer Variablen, Funktion, Klassentyp, Aufzählungstyp oder Vorlage enthalten.

162

Deklaration: "Irgendwo existiert ein Foo."

Definition: "... und hier ist es!"

125
plinth

Es gibt interessante Edge-Fälle in C++ (einige davon auch in C). Erwägen

T t;

Dies kann eine Definition oder eine Deklaration sein, abhängig davon, welcher Typ T ist:

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".

In C++ gibt es bei Verwendung von Vorlagen einen anderen Edge-Fall. 

template <typename T>
struct X { 
  static int member; // declaration
};

template<typename T>
int X<T>::member; // definition

template<>
int X<bool>::member; // declaration!

Die letzte Deklaration war nicht eine Definition. Dies ist die Deklaration einer expliziten Spezialisierung des statischen Members von X<bool>. Sie sagt dem Compiler: "Wenn es darum geht, X<bool>::member zu instantiieren, instanziieren Sie nicht die Definition des Members aus der primären Vorlage, sondern verwenden Sie die an anderer Stelle gefundene Definition." Um eine Definition vorzunehmen, müssen Sie einen Initialisierer angeben

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

Erklärung

Deklarationen teilen dem Compiler mit, dass eine Programmelement oder Name existiert. EIN Deklaration führt ein oder mehrere .__ ein. Namen in ein Programm. Deklarationen können mehr als einmal in einem Programm auftreten . Daher Klassen, Strukturen, Aufzählungsarten und andere Benutzerdefinierte Typen können für .__ deklariert werden. jede Zusammenstellungseinheit.

Definition

Definitionen geben an, welcher Code oder welche Daten der name beschreibt. Ein Name muss .__ sein. deklariert, bevor es verwendet werden kann.

31
adatapost

Aus dem C99-Standard 6,7 (5):

Eine Deklaration gibt die Interpretation und die Attribute einer Gruppe von Bezeichnern an. Eine Definition eines Bezeichners ist eine Deklaration für diesen Bezeichner, die:

  • bewirkt, dass für ein Objekt Speicher für dieses Objekt reserviert wird;
  • für eine Funktion umfasst der Funktionskörper;
  • für eine Aufzählungskonstante oder einen Typedef-Namen ist die (einzige) Deklaration des -Bezeichners.

Aus dem C++ - Standard 3.1 (2):

Eine Deklaration ist eine definition Wenn sie keine Funktion deklariert, ohne den Rumpf der Funktion anzugeben, den externen Bezeichner oder eine Verknüpfungsspezifikation und weder einen Initialisierer noch einen Funktionsrumpf enthält, deklariert sie einen statischen Datenelement in einer Klassendeklaration ist eine Klassennamendeklaration oder eine Typedef-Deklaration, eine using-Deklaration oder eine using-Direktive.

Dann gibt es einige Beispiele.

So interessant (oder nicht, aber ich bin etwas überrascht), typedef int myint; ist eine Definition in C99, aber nur eine Deklaration in C++.

20
Steve Jessop

Von wiki.answers.com:

Die Begriffsdeklaration (in C) bedeutet, dass Sie dem Compiler den Typ, die Größe und im Falle der Funktionsdeklaration den Typ und die Größe der Parameter einer beliebigen Variablen oder einen benutzerdefinierten Typ oder eine Funktion in Ihrem Programm mitteilen. No Platz wird für jede Variable im Deklarationsfall reserviert. Der Compiler weiß jedoch, wie viel Speicherplatz reserviert werden muss, falls eine Variable dieses Typs erstellt wird.

folgendes sind beispielsweise alle Deklarationen: 

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

Definition hingegen bedeutet, dass in den Deklarationen zusätzlich Speicherplatz reserviert wird. Sie können "DEFINITION = DECLARATION + SPACE RESERVATION" sagen. Nachfolgend finden Sie Definitionsbeispiele: 

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

siehe Antworten .

14
Marcin Gil

C++ 11-Update

Da ich keine passende Antwort zu C++ 11 sehe, gibt es hier eine.

Eine Deklaration ist eine Definition es sei denn, sie erklärt a/n:

  • undurchsichtige Aufzählung - enum X : int;
  • vorlagenparameter -Tin template<typename T> class MyArray;
  • parameterdeklaration - x und y in int add(int x, int y);
  • alias-Deklaration - using IntVector = std::vector<int>;
  • statische Assert-Deklaration - static_assert(sizeof(int) == 4, "Yikes!")
  • attributdeklaration (implementierungsdefiniert)
  • leere Deklaration ;

Zusätzliche Klauseln, die von der obigen Liste von C++ 03 übernommen wurden:

  • funktionsdeklaration - add in int add(int x, int y);
  • externer Bezeichner, der eine Deklaration oder einen Verknüpfungsbezeichner enthält - extern int a; oder extern "C" { ... };
  • statischer Datenmember in einer Klasse - x in class C { static int x; };
  • klassen-/Strukturdeklaration - struct Point;
  • typedef-Deklaration - typedef int Int;
  • deklaration verwenden - using std::cout;
  • using Direktive - using namespace NS;

Eine Template-Deklaration ist eine Deklaration. Eine Vorlagendeklaration ist auch eine Definition, wenn ihre Deklaration eine Funktion, eine Klasse oder ein statisches Datenelement definiert.

Beispiele aus dem Standard, die zwischen Deklaration und Definition unterscheiden, halte ich für das Verständnis der Nuancen zwischen ihnen hilfreich:

// 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
12
legends2k

Deklaration: 

int a; // this declares the variable 'a' which is of type 'int'

Auf diese Weise verknüpft die Deklaration die Variable mit einem Typ.

Nachfolgend einige Beispiele für Deklarationen.

int a;
float b;
double c;

Nun Funktionsdeklaration:

int fun(int a,int b); 

Beachten Sie das Semikolon am Ende der Funktion, so dass es nur eine Deklaration ist. Der Compiler weiß, dass irgendwo im Programm diese Funktion definiert mit diesem Prototyp ist. Wenn nun der Compiler einen Funktionsaufruf bekommt, so etwas 

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

Der Compiler gibt einen Fehler aus, der besagt, dass es keine solche Funktion gibt. Weil es keinen Prototyp für diese Funktion hat.

Beachten Sie den Unterschied zwischen zwei Programmen.

Programm 1

#include <stdio.h>
void print(int a)
{
     printf("%d",a);
}
main()
{
    print(5);
}

Dabei wird auch die Druckfunktion deklariert und definiert. Da der Funktionsaufruf nach der Definition kommt. Nun zum nächsten Programm.

Programm 2

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

Dies ist wichtig, da der Funktionsaufruf vor der Definition steht, sodass der Compiler wissen muss, ob eine solche Funktion vorhanden ist. Wir erklären also die Funktion, die den Compiler informiert.

Definition: 

Dieser Teil der Definition einer Funktion wird als Definition bezeichnet. Es sagt, was innerhalb der Funktion zu tun ist. 

void print(int a)
{
    printf("%d",a);
}

Nun mit den Variablen.

int a; //declaration
a=10; //definition 

Einige Male werden Deklaration und Definition in einer einzigen Anweisung zusammengefasst.

int a=10;
4
Sridharan

definition bedeutet, dass die eigentliche Funktion geschrieben ist und Deklaration eine einfache Deklarationsfunktion. 

void  myfunction(); //this is simple declaration

und 

void myfunction()
{
 some statement;    
}

dies ist die Definition der Funktion MyFunktion 

4
user565367

Um die Substantive zu verstehen, konzentrieren wir uns zunächst auf die Verben.

erklären - offiziell bekannt zu geben; proklamieren

define - um (jemand oder etwas) klar und vollständig darzustellen oder zu beschreiben

Wenn Sie also etwas deklarieren, sagen Sie einfach was es ist.

// declaration
int sum(int, int);

Diese Zeile deklariert eine C-Funktion namens sum, die zwei Argumente vom Typ int verwendet und eine int zurückgibt. Sie können es jedoch noch nicht verwenden.

Wenn Sie angeben, wie es tatsächlich funktioniert, ist dies die Definition davon.

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

Faustregel:

  • Eine Deklaration teilt dem Compiler mit, wie die Variablendaten im Speicher interpretiert werden sollen. Dies ist für jeden Zugriff erforderlich.

  • Eine Definition reserviert den Speicher, um die Variable zu erstellen. Dies muss genau einmal vor dem ersten Zugriff geschehen.

3
bjhend

Ähnliche Antworten finden Sie hier: Technische Interviewfragen in C

Eine Deklaration gibt dem Programm einen Namen. Ein definition liefert eine eindeutige Beschreibung einer Entität (z. B. Typ, Instanz und Funktion) innerhalb des Programms. Deklarationen können in einem bestimmten Bereich wiederholt werden, sie führen einen Namen in einen bestimmten Bereich ein. 

Eine Deklaration ist eine Definition, sofern nicht

  • Deklaration deklariert eine Funktion ohne Angabe ihres Körpers.
  • Deklaration enthält einen externen Bezeichner und keinen Initialisierer oder Funktionskörper.
  • Deklaration ist die Deklaration eines statischen Klassendatenelements ohne Klassendefinition.
  • Deklaration ist eine Klassennamensdefinition.

Eine Definition ist eine Deklaration, es sei denn:

  • Definition definiert ein statisches Klassendatenelement.
  • Definition definiert eine Nicht-Inline-Memberfunktion.
2
Santosh

Könnten Sie nicht so allgemein wie möglich angeben, dass eine Deklaration eine Kennung ist, in der kein Speicher zugeordnet ist, und eine Definition tatsächlich Speicherkapazität aus einer deklarierten Kennung zuweist? 

Ein interessanter Gedanke: Eine Vorlage kann keinen Speicher zuordnen, bis die Klasse oder Funktion mit den Typinformationen verknüpft ist. Ist der Vorlagenbezeichner also eine Deklaration oder Definition? Es sollte eine Deklaration sein, da kein Speicher zugeordnet ist und Sie lediglich die Vorlagenklasse oder -funktion "prototypen".

2
user154171

Um den Unterschied zwischen Deklaration und Definition zu verstehen, müssen Sie den Assembly-Code sehen:

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)

und das ist nur Definition:

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)

Wie Sie sehen, ändert sich nichts.

Die Deklaration unterscheidet sich von der Definition, da sie nur vom Compiler verwendete Informationen enthält. Zum Beispiel weist uint8_t den Compiler an, die asm-Funktion movb zu verwenden.

Siehst du das:

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

Deklaration hat keine gleichwertige Anweisung, da sie nicht ausgeführt werden muss.

Des Weiteren teilt die Deklaration dem Compiler den Gültigkeitsbereich der Variablen mit.

Wir können sagen, dass Deklaration eine Information ist, die vom Compiler verwendet wird, um die korrekte Verwendung der Variablen festzulegen und für wie lange ein Teil der Variablen zu einer bestimmten Variable gehört.

2
princio

Deklaration bedeutet, einer Variable Namen und Typ zu geben (im Falle einer Variablendeklaration) ZB: 

 int i;  

oder Name, Rückgabetyp und Parameterart (en) einer Funktion ohne Rumpf geben (im Falle einer Funktionsdeklaration)

z.B: 

int max(int, int);

während Definition bedeutet, einer Variablen einen Wert zuzuordnen (im Falle einer Variablendefinition) . zB:

i = 20;

oder eine Funktion (Funktion) einer Funktion bereitstellen/hinzufügen, wird als Funktionsdefinition bezeichnet.

z.B: 

 int max(int a, int b)
 {
    if(a>b)   return a;
    return b;  
 }

viele Zeitdeklarationen und Definitionen können zusammen als:

int i=20;   

und

int max(int a, int b)
{
    if(a>b)   return a;
    return b;    
} 

In obigen Fällen definieren und deklarieren wir die Variablen i und die Funktion max ().

1
Puneet Purohit

Das hört sich wirklich kitschig an, aber es ist der beste Weg, die Begriffe im Kopf zu behalten:

Erklärung: Bild Thomas Jefferson bei einer Rede ... "Ich erkläre hiermit, dass dieser Foo in diesem Quellcode existiert !!!"

Definition: Bild ein Wörterbuch, Sie suchen nach Foo und was es eigentlich bedeutet.

1
It'sPete

Gemäß dem GNU C-Bibliothekshandbuch ( http://www.gnu.org/software/libc/manual/html_node/Header-Files.html )

In C liefert eine Deklaration lediglich Informationen darüber, dass eine Funktion oder Variable existiert, und gibt ihren Typ an. Bei einer Funktionsdeklaration können auch Informationen zu den Typen der Argumente angegeben werden. Deklarationen haben den Zweck, dass der Compiler Verweise auf die deklarierten Variablen und Funktionen korrekt verarbeiten kann. Andererseits definiert eine Definition tatsächlich Speicher für eine Variable oder sagt, was eine Funktion tut.

1
LinuxBabe

Eine Deklaration präsentiert dem Compiler einen Symbolnamen. Eine Definition ist eine Deklaration, die Platz für das Symbol reserviert.

int f(int x); // function declaration (I know f exists)

int f(int x) { return 2*x; } // declaration and definition
0
hdante

Phasen einer ausführbaren Generierung: 

(1) Vorprozessor -> (2) Übersetzer/Compiler -> (3) Linker

In Stufe 2 (Übersetzer/Compiler) teilen Deklarationsanweisungen in unserem Code dem Compiler mit, dass diese Dinge in Zukunft verwendet werden, und Sie können später Definitionen finden. Dies bedeutet:

Übersetzer sicherstellen, dass: was ist was? bedeutet Deklaration 

und (3) die Stufe (Linker) muss definiert werden, um die Dinge zu binden 

Linker stellt sicher, dass: wo ist was? bedeutet Definition

0
Jeet Parikh

Es gibt einige sehr klare Definitionen in K & R (2. Auflage); Es hilft, sie an einem Ort zu platzieren und als eine zu lesen:

"Definition" bezieht sich auf den Ort, an dem die Variable erstellt oder Speicher zugewiesen wird. "Deklaration" bezieht sich auf die Stellen, an denen die Art der Variablen angegeben ist, aber kein Speicher zugewiesen ist. [p. 33]

...

Es ist wichtig, zwischen der Deklaration einer externen Variablen und ihrer Definition zu unterscheiden. Eine Deklaration kündigt die Eigenschaften einer Variablen an (hauptsächlich ihren Typ). Eine Definition bewirkt auch, dass Speicherplatz reserviert wird. Wenn die Zeilen

int sp;
double val[MAXVAL]

erscheinen sie außerhalb einer Funktion, definieren die externen Variablen sp und val, bewirken, dass der Speicher reserviert wird, und dienen auch als Deklaration für den Rest dieser Quelldatei .

Auf der anderen Seite die Linien

extern int sp;
extern double val[];

deklarieren für den Rest der Quelldatei, dass sp ein int ist und dass val ein double Array ist (dessen Größe an anderer Stelle bestimmt wird) Sie erstellen jedoch keine Variablen und reservieren keinen Speicherplatz für sie.

Unter allen Dateien, aus denen sich das Quellprogramm zusammensetzt, darf es nur ein Definition einer externen Variablen geben. ... Arraygrößen müssen bei der Definition angegeben werden, sind jedoch bei einer extern -Deklaration optional. [pp. 80-81]

...

Erklärungen geben die Interpretation an, die jeder Kennung gegeben wird; Sie reservieren nicht unbedingt Speicherplatz für die Kennung. Deklarationen, die Speicher reservieren, heißen Definitionen. [p. 210]

0
Brad Solomon

Mein Lieblingsbeispiel ist "int Num = 5". Hier ist Ihre Variable 1. Definiert als Int 2. Deklariert als Num und 3. Instanziert mit einem Wert von fünf. Wir

  • Definieren Sie den Typ eines Objekts, das eingebaut sein kann, oder eine Klasse oder Struktur.
  • Deklarieren Sie den Namen eines Objekts. Daher wurde alles mit einem Namen deklariert, zu dem Variablen, Funktionen usw. gehören.

Mit einer Klasse oder Struktur können Sie ändern, wie Objekte definiert werden, wenn sie später verwendet werden. Zum Beispiel

  • Man kann eine heterogene Variable oder ein Array deklarieren, die nicht spezifisch definiert sind.
  • Mit einem Offset in C++ können Sie ein Objekt definieren, das keinen deklarierten Namen hat.

Wenn wir das Programmieren lernen, werden diese beiden Begriffe oft verwirrt, weil wir beide gleichzeitig machen. 

0
Jason K.

Das Konzept der Deklaration und Definition bildet eine Gefahr, wenn Sie die externe Speicherklasse verwenden, da sich Ihre Definition an einem anderen Ort befindet und Sie die Variable in Ihrer lokalen Codedatei (Seite) deklarieren. Ein Unterschied zwischen C und C++ besteht darin, dass in C die Deklarationen normalerweise am Anfang einer Funktion oder Codepage ausgeführt werden. In C++ ist das nicht so. Sie können sich an einem Ort Ihrer Wahl anmelden.

0
achoora