¿Cuál es la diferencia entre una definición y una declaración?

858

El significado de ambos se me escapa.

Maciek
fuente
9191
@Lasse: no es cierto. Una definición define y declara ;-)
Steve Jessop
13
Francamente, tuve muchos problemas para aprender cuál era cuál, así que no encontré los nombres obvios. No tuve ningún problema con los significados, solo qué nombres asociar con los significados.
David Thornley
66
Aún así, no es una pregunta duplicada, ya que esta pregunta sobre C / C ++, mientras que esa otra pregunta se hizo sobre todos los idiomas, o ninguno, en general. Solo tiene respuestas duplicadas (ya que en esa otra pregunta, algunas respuestas optaron por ignorar todo el lenguaje excepto C y / o C ++).
Steve Jessop
55
@DavidThornley Utilizo este truco: una definición da una descripción más precisa de una variable o función dada. Para recordar esto, recuerdo que el medio de la palabra "definición" se parece a la palabra "más fino". :)
Marco Leogrande
44
Es sorprendente la cantidad de basura que hay en esta pregunta. Simplemente muestra cuánto se malinterpreta este lenguaje y cómo se propagan esos malentendidos de manera rutinaria . Es triste, de verdad.
Carreras de ligereza en órbita el

Respuestas:

858

Una declaración introduce un identificador y describe su tipo, ya sea un tipo, objeto o función. Una declaración es lo que el compilador necesita para aceptar referencias a ese identificador. Estas son declaraciones:

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

Una definición en realidad instancia / implementa este identificador. Es lo que necesita el vinculador para vincular referencias a esas entidades. Estas son definiciones correspondientes a las declaraciones anteriores:

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

Se puede usar una definición en lugar de una declaración.

Un identificador se puede declarar con la frecuencia que desee. Por lo tanto, lo siguiente es legal en C y 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);

Sin embargo, debe definirse exactamente una vez. Si olvida definir algo que ha sido declarado y referenciado en alguna parte, entonces el vinculador no sabe a qué vincular las referencias y se queja de la falta de símbolos. Si define algo más de una vez, el vinculador no sabe a qué definiciones vincular referencias y se queja de símbolos duplicados.


Dado que el debate sobre qué es una declaración de clase frente a una definición de clase en C ++ sigue apareciendo (en respuestas y comentarios a otras preguntas), pegaré una cita del estándar de C ++ aquí.
En 3.1 / 2, C ++ 03 dice:

Una declaración es una definición a menos que [...] sea una declaración de nombre de clase [...].

3.1 / 3 luego da algunos ejemplos. Entre ellos:

[Ejemplo: [...]
struct S {int a; int b; }; // define S, S :: a y S :: b [...]
estructura S; // declara S
—Ejemplo

Para resumir: el estándar C ++ considera struct x;que es una declaración y struct x {};una definición . (En otras palabras, "declaración hacia adelante" es un nombre inapropiado , ya que no hay otras formas de declaraciones de clase en C ++).

Gracias a litb (Johannes Schaub) que desenterró el capítulo y el verso en una de sus respuestas.

sbi
fuente
2
@unknown: tu compilador está roto o has copiado mal el código de sbi. Por ejemplo, 6.7.2 (2) en N1124: "Todas las declaraciones que se refieren al mismo objeto o función deberán tener un tipo compatible; de ​​lo contrario, el comportamiento no está definido".
Steve Jessop
44
@Brian: "extern int i;" dice que soy int en alguna parte, no te preocupes por eso. "int i;" significa que i es un int, y su dirección y alcance se determinan aquí.
David Thornley
12
@Brian: Estás equivocado. extern int ies una declaración, ya que solo introduce / especifica i. Puede tener tantos extern int ien cada unidad de compilación como desee. int iSin embargo, es una definición. Denota el espacio para que el entero esté en esta unidad de traducción y aconseja al vinculador que vincule todas las referencias a iesta entidad. Si tiene más o menos de una de estas definiciones, el vinculador se quejará.
sbi
44
@Brian int i;en archivo / alcance global o alcance de función es una definición tanto en C como en C ++. En C porque asigna almacenamiento, y en C ++ porque no tiene el especificador externo o una especificación de enlace. Esto equivale a lo mismo, que es lo que dice sbi: en ambos casos, esta declaración especifica el objeto al que deben vincularse todas las referencias a "i" en ese ámbito.
Steve Jessop
44
@unknown, tenga cuidado porque no puede volver a declarar miembros en el ámbito de clase : struct A { double f(int, double); double f(int, double); };inválido, por supuesto. Sin embargo, está permitido en otros lugares. Hay algunos lugares donde se puede declarar cosas, pero no definen, también: void f() { void g(); }válida, pero no el siguiente: void f() { void g() { } };. ¿Qué es una definición y qué declaración tiene reglas sutiles cuando se trata de plantillas? ¡Cuidado! +1 para una buena respuesta sin embargo.
Johannes Schaub - litb
168

Desde el estándar C ++ sección 3.1:

Una declaración introduce nombres en una unidad de traducción o redeclara nombres introducidos por declaraciones anteriores. Una declaración especifica la interpretación y los atributos de estos nombres.

El siguiente párrafo establece (énfasis mío) que una declaración es una definición a menos que ...

... declara una función sin especificar el cuerpo de la función:

void sqrt(double);  // declares sqrt

... declara un miembro estático dentro de una definición de clase:

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

... declara un nombre de clase:

class Y;

... contiene la externpalabra clave sin un inicializador o cuerpo de función:

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

... o es una typedefo usingdeclaración.

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

Ahora, por la gran razón por la cual es importante entender la diferencia entre una declaración y una definición: la regla de una definición . De la sección 3.2.1 del estándar C ++:

Ninguna unidad de traducción contendrá más de una definición de variable, función, tipo de clase, tipo de enumeración o plantilla.

Michael Kristofik
fuente
"declara un miembro estático dentro de una definición de clase" - Esto es cierto incluso si el miembro estático se inicializa, ¿correcto? ¿Podemos hacer el ejemplo struct x {static int b = 3; };?
RJFalconer
@RJFalconer Tienes razón; la inicialización no necesariamente convierte una declaración en una definición (contrario a lo que uno podría esperar; ciertamente esto me pareció sorprendente). Su modificación al ejemplo es realmente ilegal a menos bque también se declare const. Consulte stackoverflow.com/a/3536513/1858225 y daniweb.com/software-development/cpp/threads/140739/… .
Kyle Strand
1
Esto es interesante para mi Según su respuesta, parece que en C ++, una declaración también es una definición (con excepciones), mientras que en el estándar C está redactada desde la otra perspectiva (C99, sección 6.7, Declaraciones): "Una definición de un identificador es una declaración para ese identificador que: [seguido de criterios para diferentes casos] ". Diferentes formas de verlo, supongo. :)
Victor Zamanian
La declaración es para que el compilador acepte un nombre (para decirle al compilador que el nombre es legal, el nombre se introduce con intención, no un error tipográfico). Definición es donde se asocia un nombre y su contenido. El vinculador utiliza la definición para vincular una referencia de nombre al contenido del nombre.
Gab 是 好人
137

Declaración: "En algún lugar, existe un foo".

Definición: "... y aquí está!"

pedestal
fuente
3
La declaración es para que el compilador acepte un nombre (para decirle al compilador que el nombre es legal, el nombre se introduce con intención, no un error tipográfico). Definición es donde se asocia un nombre y su contenido. El vinculador utiliza la definición para vincular una referencia de nombre al contenido del nombre.
Gab 是 好人
46

Hay casos extremos interesantes en C ++ (algunos de ellos también en C). Considerar

T t;

Eso puede ser una definición o una declaración, dependiendo de qué tipo Tes:

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 ++, cuando se usan plantillas, hay otro caso límite.

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

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

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

La última declaración no fue una definición. Es la declaración de una especialización explícita del miembro estático de X<bool>. Le dice al compilador: "Si se trata de crear instancias X<bool>::member, no cree una instancia de la definición del miembro de la plantilla principal, sino que use la definición que se encuentra en otro lugar". Para que sea una definición, debe proporcionar un inicializador

template<>
int X<bool>::member = 1; // definition, belongs into a .cpp file.
Johannes Schaub - litb
fuente
35

Declaración

Las declaraciones le dicen al compilador que existe un elemento o nombre del programa. Una declaración introduce uno o más nombres en un programa. Las declaraciones pueden ocurrir más de una vez en un programa. Por lo tanto, se pueden declarar clases, estructuras, tipos enumerados y otros tipos definidos por el usuario para cada unidad de compilación.

Definición

Las definiciones especifican qué código o datos describe el nombre. Se debe declarar un nombre antes de poder usarlo.

Adatapost
fuente
¿No es que incluso puedes definir clases y enumeraciones en cada unidad de compilación? Al menos pongo definiciones de clase en mis encabezados y las incluyo por todas partes. Er, class foo {}; es una definición de clase , ¿no?
sbi
1
Si. Sin embargo, "clase foo"; Es una declaración. Le dice al compilador que foo es una clase. "class foo {};" Es una definición. Le dice al compilador exactamente qué clase de clase es foo.
David Thornley
1
La excepción son los nombres de los miembros de la clase que se pueden usar antes de declararlos.
Johannes Schaub - litb
1
Sí, a eso me refería. Entonces puede hacer lo siguiente: struct foo {void b () {f (); } nulo f (); }, f es visible aunque no se haya declarado todavía. Lo siguiente también funciona: struct foo {void b (int = bar ()); typedef int bar; } ;. Es visible antes de su declaración en "todos los cuerpos de funciones, argumentos predeterminados, constructor ctor-initializers". No en el tipo de devolución :(
Johannes Schaub - litb
1
@litb: No es visible antes de su declaración, es solo que el uso del identificador se mueve detrás de la declaración. Sí, lo sé, el efecto es el mismo para muchos casos. Pero no para todos los casos, por eso creo que deberíamos usar la explicación precisa. - Uy, espera. ¿Es visible en los argumentos predeterminados? Bueno, eso seguramente causa estragos con mi comprensión. Maldita sea! <pouts>
sbi
22

Del estándar C99, 6.7 (5):

Una declaración especifica la interpretación y los atributos de un conjunto de identificadores. Una definición de un identificador es una declaración para ese identificador que:

  • para un objeto, hace que el almacenamiento esté reservado para ese objeto;
  • para una función, incluye el cuerpo de la función;
  • para una constante de enumeración o nombre typedef, es la (única) declaración del identificador.

Del estándar C ++, 3.1 (2):

Una declaración es una definición a menos que declare una función sin especificar el cuerpo de la función, contiene el especificador externo o una especificación de vinculación y ni un inicializador ni un cuerpo de función, declara un miembro de datos estáticos en una declaración de clase, es un declaración de nombre de clase, o es una declaración typedef, una declaración de uso o una directiva de uso.

Entonces hay algunos ejemplos.

De manera interesante (o no, pero me sorprende un poco), typedef int myint;es una definición en C99, pero solo una declaración en C ++.

Steve Jessop
fuente
@onebyone: En cuanto a typedef, ¿no significa eso que podría repetirse en C ++, pero no en C99?
sbi
Eso es lo que me sorprendió, y en lo que respecta a una sola unidad de traducción, sí, existe esa diferencia. Pero claramente se puede repetir un typedef en C99 en diferentes unidades de traducción. C no tiene una "regla de una definición" explícita como C ++, por lo que las reglas que tiene solo lo permiten. C ++ eligió cambiarlo a una declaración, pero también la regla de una definición enumera a qué tipo de cosas se aplica, y typedefs no es una de ellas. Por lo tanto, las repeticiones se permitirían en C ++ bajo el ODR como está redactado, incluso si un typedef fuera una definición. Parece innecesariamente exigente.
Steve Jessop
... pero supongo que esa lista en el ODR en realidad enumera todas las cosas de las que es posible tener definiciones. Si es así, entonces la lista es realmente redundante y está ahí para ser útil.
Steve Jessop
¿Qué dice la definición ODR del estándar sobre las definiciones de clase? Ellos tienen que ser repetido.
sbi
2
@sbi: ODR dice "(1) Ninguna unidad de traducción contendrá más de una definición de cualquier ... tipo de clase" y "(5) Puede haber más de una definición de un tipo de clase ... en un programa siempre que cada definición aparece en una unidad de traducción diferente "y luego algunos requisitos adicionales que equivalen a" las definiciones son las mismas ".
Steve Jessop
17

De wiki.answers.com:

El término declaración significa (en C) que le está informando al compilador sobre el tipo, tamaño y, en caso de declaración de función, tipo y tamaño de sus parámetros de cualquier variable, o tipo o función definidos por el usuario en su programa. No se reserva espacio en la memoria para ninguna variable en caso de declaración. Sin embargo, el compilador sabe cuánto espacio reservar en caso de que se cree una variable de este tipo.

por ejemplo, las siguientes son todas las declaraciones:

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

La definición, por otro lado, significa que además de todas las cosas que hace la declaración, el espacio también está reservado en la memoria. Puede decir "DEFINICIÓN = DECLARACIÓN + RESERVA DE ESPACIO" a continuación hay ejemplos de definición:

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

ver respuestas .

Marcin Gil
fuente
3
Esto también está mal (aunque mucho más cerca que los demás): struct foo {};es una definición , no una declaración. Una declaración de foosería struct foo;. A partir de eso, el compilador no sabe cuánto espacio reservar para los fooobjetos.
sbi
1
@Marcin: sbi dice que "el compilador sabe cuánto espacio reservar en caso de que se cree una variable de este tipo" no siempre es cierto. struct foo;es una declaración, pero no le dice al compilador el tamaño de foo. Añadiría que struct _tagExample { int a; int b; };es una definición. Entonces, en este contexto, es engañoso llamarlo una declaración. Por supuesto, es una, ya que todas las definiciones son declaraciones, pero parece estar sugiriendo que no es una definición. Es una definición, de _tagExample.
Steve Jessop
1
@Marcin Gil: lo que significa que el wiki "Respuestas" no siempre es exacto. Tengo que votar a favor de la información errónea aquí.
David Thornley
1
Aprendemos que lo que cita Adatapost es cierto pero no responde (IMO) realmente a la pregunta. Lo que Marcin citó es falso. Citar los estándares es cierto y responde la pregunta, pero es muy difícil de entender.
Steve Jessop
1
@David Thornley - no es un problema :) De esto se trata este sitio. Nosotros seleccionamos y verificar información.
Marcin Gil
13

Actualización de C ++ 11

Como no veo una respuesta pertinente a C ++ 11, aquí hay una.

Una declaración es una definición a menos que declare a / n:

  • enum opaco enum X : int;
  • parámetro de plantilla - T entemplate<typename T> class MyArray;
  • declaración de parámetros - x e y enint add(int x, int y);
  • declaración de alias using IntVector = std::vector<int>;
  • declaración de afirmación estática static_assert(sizeof(int) == 4, "Yikes!")
  • declaración de atributo (definida por la implementación)
  • declaración vacía ;

Cláusulas adicionales heredadas de C ++ 03 por la lista anterior:

  • declaración de la función - añadir enint add(int x, int y);
  • especificador externo que contiene declaración o un especificador de vinculación, extern int a;oextern "C" { ... };
  • miembro de datos estáticos en una clase - x enclass C { static int x; };
  • declaración de clase / estructura - struct Point;
  • declaración typedef typedef int Int;
  • utilizando declaración - using std::cout;
  • usando directiva - using namespace NS;

Una declaración de plantilla es una declaración. Una declaración de plantilla también es una definición si su declaración define una función, una clase o un miembro de datos estático.

Ejemplos del estándar que diferencia entre declaración y definición que encontré útil para comprender los matices entre ellos:

// 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
legends2k
fuente
6

Definición :

extern int a;      // Declaration 
int a;             // Definition
a = 10             // Initialization
int b = 10;        // Definition & Initialization

La definición asocia la variable con un tipo y asigna memoria, mientras que la declaración solo especifica el tipo pero no asigna memoria. La declaración es más útil cuando desea hacer referencia a la variable antes de la definición.

* No confunda definición con inicialización. Ambos son diferentes, la inicialización le da valor a la variable. Ver el ejemplo anterior.

Los siguientes son algunos ejemplos de definición.

int a;
float b;
double c;

Ahora declaración de función:

int fun(int a,int b); 

Tenga en cuenta el punto y coma al final de la función, por lo que dice que es solo una declaración. El compilador sabe que en algún lugar del programa esa función se definirá con ese prototipo. Ahora, si el compilador obtiene una función, llame a algo como esto

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

El compilador arrojará un error diciendo que no existe tal función. Porque no tiene ningún prototipo para esa función.

Tenga en cuenta la diferencia entre dos programas.

Programa 1

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

En esto, la función de impresión se declara y define también. Dado que la llamada a la función viene después de la definición. Ahora vea el próximo programa.

Programa 2

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

Es esencial porque la llamada a la función precede a la definición, por lo que el compilador debe saber si existe tal función. Entonces declaramos la función que informará al compilador.

Definición :

Esta parte de definir una función se llama Definición. Dice qué hacer dentro de la función.

void print(int a)
{
    printf("%d",a);
}
SRIDHARAN
fuente
2
int a; //declaration; a=10; //definitionEsto está completamente mal. Cuando se habla de objetos de duración de almacenamiento automático (objetos declarados dentro de una definición de función que no se declara con otro especificador de clase de almacenamiento como extern), estas siempre son definiciones.
Joey Pabalinas
La principal diferencia a entender es que una declaración dice "algo existe en algún lugar que tiene estos rasgos (tipo, etc.)", mientras que una definición dice "Estoy declarando algo con estos rasgos, y también lo estoy instanciando aquí como bien." Dado que no puede reenviar objetos de duración de almacenamiento automático como ese, siempre serán definiciones.
Joey Pabalinas
Excepto por algunos casos extraños de esquina de typedef que siempre olvido, una regla general es que todas las definiciones son declaraciones. Piénsalo; cuando está creando una instancia de algo, también debe decirle al compilador que esa cosa existe y cuáles son sus rasgos correctos?
Joey Pabalinas
Actualizó la respuesta según su primer comentario. sin embargo, no estoy de acuerdo con este comentario "cuando estás creando una instancia de algo, también debes decirle al compilador que esa cosa existe". No siempre especificamos el tipo de lhs al crear instancias. Ej: a = 10. No estamos especificando ningún "rasgo" de un aquí.
SRIDHARAN
4

definición significa función real escrita y declaración significa función simple para declarar, por ejemplo

void  myfunction(); //this is simple declaration

y

void myfunction()
{
 some statement;    
}

esta es la definición de la función myfunction

Flexo
fuente
1
¿Y qué hay de los tipos y objetos?
sbi
4

Regla de oro:

  • Una declaración le dice al compilador cómo interpretar los datos de la variable en la memoria. Esto es necesario para cada acceso.

  • Una definición reserva la memoria para hacer que la variable exista. Esto tiene que suceder exactamente una vez antes del primer acceso.

bjhend
fuente
2
Esto solo se aplica a los objetos. ¿Qué pasa con los tipos y funciones?
Carreras de ligereza en órbita el
4

Para entender los sustantivos, centrémonos primero en los verbos.

declarar : anunciar oficialmente; proclamar

definir - para mostrar o describir (alguien o algo) clara y completamente

Entonces, cuando declaras algo, solo dices qué es .

// declaration
int sum(int, int);

Esta línea declara una función llamada C sumque toma dos argumentos de tipo inty devuelve un int. Sin embargo, aún no puedes usarlo.

Cuando proporcionas cómo funciona realmente , esa es la definición.

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

Para comprender la diferencia entre declaración y definición, necesitamos ver el código de ensamblaje:

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)

y esta es solo la definición:

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)

Como puedes ver nada cambia.

La declaración es diferente de la definición porque proporciona información utilizada solo por el compilador. Por ejemplo, uint8_t le dice al compilador que use la función asm movb.

Mira eso:

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

La declaración no tiene una instrucción equivalente porque no es algo que se ejecute.

Además, la declaración le dice al compilador el alcance de la variable.

Podemos decir que la declaración es una información utilizada por el compilador para establecer el uso correcto de la variable y por cuánto tiempo alguna memoria pertenece a cierta variable.

princio
fuente
2

¿No podría decir en los términos más generales posibles, que una declaración es un identificador en el que no se asigna almacenamiento y una definición realmente asigna el almacenamiento de un identificador declarado?

Una idea interesante: una plantilla no puede asignar almacenamiento hasta que la clase o función esté vinculada con la información de tipo. Entonces, ¿el identificador de plantilla es una declaración o definición? Debería ser una declaración ya que no se asigna almacenamiento, y simplemente está 'creando prototipos' de la clase o función de plantilla.


fuente
1
Su definición no es per se incorrecta, pero la "definición de almacenamiento" siempre parece incómoda cuando se trata de definiciones de funciones. Con respecto a las plantillas: Esta template<class T> struct foo;es una declaración de plantilla , y también lo es template<class T> void f();. Las definiciones de plantilla reflejan las definiciones de clase / función de la misma manera. (Tenga en cuenta que el nombre de una plantilla no es un nombre de tipo o función . Un lugar donde puede ver esto es cuando no puede pasar una plantilla como parámetro de tipo de otra plantilla. Si desea pasar plantillas en lugar de tipos, necesita parámetros de plantilla de plantilla. )
sbi
Convino en que la 'definición de almacenamiento' es incómoda, especialmente con respecto a las definiciones de funciones. La declaración es int foo () y la definición es int foo () {// algún código aquí ..}. Por lo general, necesito envolver mi pequeño cerebro con conceptos que conozco: el 'almacenamiento' es una forma de mantenerlo directo al menos para mí ... :)
2

Encuentra respuestas similares aquí: Preguntas de la entrevista técnicos en C .

Una declaración proporciona un nombre al programa; Una definición proporciona una descripción única de una entidad (por ejemplo, tipo, instancia y función) dentro del programa. Las declaraciones pueden repetirse en un ámbito dado, introduce un nombre en un ámbito determinado.

Una declaración es una definición a menos que:

  • La declaración declara una función sin especificar su cuerpo,
  • La declaración contiene un especificador externo y ningún inicializador o cuerpo de función,
  • Declaración es la declaración de un miembro de datos de clase estática sin una definición de clase,
  • Declaración es una definición de nombre de clase,

Una definición es una declaración a menos que:

  • La definición define un miembro de datos de clase estática,
  • La definición define una función miembro no en línea.
Santosh
fuente
1

Esto va a sonar realmente cursi, pero es la mejor manera en que he podido mantener los términos en mi cabeza:

Declaración: Imagine a Thomas Jefferson dando un discurso ... "¡DECLARO QUE ESTA FOO EXISTE EN ESTE CÓDIGO DE FUENTE!"

Definición: imagina un diccionario, estás buscando Foo y lo que realmente significa.

EsPete
fuente
1

Una declaración presenta un nombre de símbolo al compilador. Una definición es una declaración que asigna espacio para el símbolo.

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

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

De acuerdo con el manual de la biblioteca GNU C ( http://www.gnu.org/software/libc/manual/html_node/Header-Files.html )

En C, una declaración simplemente proporciona información de que existe una función o variable y da su tipo. Para una declaración de función, también se puede proporcionar información sobre los tipos de sus argumentos. El propósito de las declaraciones es permitir que el compilador procese correctamente las referencias a las variables y funciones declaradas. Una definición, por otro lado, en realidad asigna almacenamiento para una variable o dice lo que hace una función.

LinuxBabe
fuente
0

El concepto de Declaración y Definición formará una trampa cuando use la clase de almacenamiento externo porque su definición estará en otra ubicación y declarará la variable en su archivo de código local (página). Una diferencia entre C y C ++ es que en C usted las declaraciones se realizan normalmente al comienzo de una función o página de códigos. En C ++ no es así. Puede declarar en el lugar que elija.

Achoora
fuente
1
Esto confunde la declaración con la definición y es simplemente incorrecto.
sbi
0

Mi ejemplo favorito es "int Num = 5" aquí su variable es 1. definida como int 2. declarada como Num y 3. instanciada con un valor de cinco. Nosotros

  • Defina el tipo de un objeto, que puede ser incorporado o una clase o estructura.
  • Declare el nombre de un objeto, por lo que se ha declarado cualquier cosa con un nombre que incluya variables, funciones, etc.

Una clase o estructura le permite cambiar cómo se definirán los objetos cuando se use más tarde. Por ejemplo

  • Se puede declarar una variable o matriz heterogénea que no se define específicamente.
  • Usando un desplazamiento en C ++ puede definir un objeto que no tiene un nombre declarado.

Cuando aprendemos a programar estos dos términos a menudo se confunden porque a menudo hacemos ambos al mismo tiempo.

Jason K.
fuente
No entiendo por qué tanta gente votó por la respuesta de sbi. Voté la respuesta de bjhend, que era bastante buena, concisa, precisa y mucho más oportuna que la mía. Me entristeció ver que fui la primera persona en hacerlo en 4 años.
Jason K.
0

Etapas de una generación ejecutable:

(1) preprocesador -> (2) traductor / compilador -> (3) enlazador

En la etapa 2 (traductor / compilador), las declaraciones de declaración en nuestro código le dicen al compilador que estas cosas las vamos a usar en el futuro y puede encontrar la definición más adelante, el significado es:

traductor asegúrese de que: ¿qué es qué? significa declaración

y (3) la etapa (enlazador) necesita definición para unir las cosas

Linker asegúrese de que: ¿ dónde está qué? significa definición

Jeet Parikh
fuente
0

Hay algunas definiciones muy claras esparcidas por K&R (segunda edición); ayuda ponerlos en un solo lugar y leerlos como uno:

"Definición" se refiere al lugar donde se crea la variable o se le asigna almacenamiento; "declaración" se refiere a los lugares donde se indica la naturaleza de la variable pero no se asigna almacenamiento. [pags. 33]

...

Es importante distinguir entre la declaración de una variable externa y su definición . Una declaración anuncia las propiedades de una variable (principalmente su tipo); una definición también hace que se guarde el almacenamiento. Si las lineas

int sp;
double val[MAXVAL]

aparecen fuera de cualquier función, definen las variables externas spy valhacen que se guarde el almacenamiento, y también sirven como declaración para el resto del archivo fuente.

Por otro lado, las lineas

extern int sp;
extern double val[];

declaran para el resto del archivo fuente que spes un inty que vales una doublematriz (cuyo tamaño se determina en otro lugar), pero no crean las variables ni reservan almacenamiento para ellos.

Debe haber solo una definición de una variable externa entre todos los archivos que componen el programa fuente. ... Los tamaños de matriz deben especificarse con la definición, pero son opcionales con una externdeclaración. [páginas. 80-81]

...

Las declaraciones especifican la interpretación dada a cada identificador; no necesariamente reservan el almacenamiento asociado con el identificador. Las declaraciones que reservan almacenamiento se denominan definiciones . [pags. 210]

Brad Solomon
fuente
-1

Declaración significa dar nombre y tipo a una variable (en caso de declaración de variable), por ejemplo:

int i;

o dar nombre, tipo de retorno y tipo de parámetro (s) a una función sin cuerpo (en caso de declaración de función), por ejemplo:

int max(int, int);

mientras que definición significa asignar valor a una variable (en caso de definición de variable), por ejemplo:

i = 20;

o proporcionar / agregar cuerpo (funcionalidad) a una función se denomina definición de función, por ejemplo:

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

muchas declaraciones y definiciones de tiempo se pueden hacer juntas como:

int i=20;

y:

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

En los casos anteriores definimos y declaramos variables iy function max().

Puneet Purohit
fuente
la media real de definición si se debe asignar valor / cuerpo a una variable / función, mientras que la declaración significa proporcionar nombre, escribir a una variable / función
Puneet Purohit
Puede definir algo sin asignarle un valor.
Carreras de ligereza en órbita el
1
Justo así:int x;
ligereza corre en órbita el
es una declaración de variable x no su definición
Puneet Purohit
2
No, son los dos. Estás confundiendo definición con inicialización.
Carreras de ligereza en órbita el