que - ¿Cuál es la diferencia entre una definición y una declaración?
mision y vision ejemplos (24)
El significado de ambos me elude.
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 un / n:
- enumeración opaca -
enum X : int;
- parámetro de plantilla - T en
template<typename T> class MyArray;
- declaración de parámetros - x e y en
int add(int x, int y);
- declaración de alias -
using IntVector = std::vector<int>;
- declaración de
static_assert(sizeof(int) == 4, "Yikes!")
estática -static_assert(sizeof(int) == 4, "Yikes!")
- declaración de atributo (implementación definida)
- declaración vacía
Cláusulas adicionales heredadas de C ++ 03 por la lista anterior:
- declaración de función - agregar en
int add(int x, int y);
- Especificador externo que contiene una declaración o un especificador de vinculación -
extern int a;
oextern "C" { ... };
- miembro de datos estáticos en una clase - x en
class C { static int x; };
class C { static int x; };
- declaración de clase / estructura -
struct Point;
- declaración typedef -
typedef int Int;
- utilizando declaración -
using std::cout;
- uso de 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áticos.
Ejemplos de la norma que diferencia entre declaración y definición que me parecieron útiles 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
¿No podría declarar en los términos más generales posibles, que una declaración es un identificador en el que no se asigna ningún almacenamiento y que una definición asigna realmente el almacenamiento de un identificador declarado?
Un pensamiento interesante: una plantilla no puede asignar almacenamiento hasta que la clase o función se vincule 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 un prototipo" de la clase de plantilla o función.
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 una función o variable existe 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.
De la norma 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 se reserve para ese objeto;
- para una función, incluye el cuerpo de la función;
- para una constante de enumeración o un 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 la 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.
Luego hay algunos ejemplos.
Tan interesante (o no, pero estoy un poco sorprendido por eso), typedef int myint;
es una definición en C99, pero solo una declaración en C ++.
De la sección 3.1 de la norma C ++:
Una declaración introduce nombres en una unidad de traducción o vuelve a declarar 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 palabra clave extern
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 un typedef
o declaración using
.
typedef long LONG_32; // declares LONG_32
using namespace std; // declares std
Ahora por la gran razón por la que 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 cualquier variable, función, tipo de clase, tipo de enumeración o plantilla.
De wiki.answers.com:
El término declaración significa (en C) que le está diciendo al compilador sobre el tipo, el tamaño y en el caso de la declaración de la función, el tipo y el tamaño de sus parámetros de cualquier variable, o el tipo o función definida por el usuario en su programa. No hay espacio reservado 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);
Por otra parte, la definición significa que, además de todo lo que hace la declaración, el espacio también se reserva 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 Answers .
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)
p.ej:
int max(int, int);
mientras que definición significa asignar valor a una variable (en caso de definición de variable). p.ej:
i = 20;
o proporcionar / agregar cuerpo (funcionalidad) a una función se llama definición de función.
p.ej:
int max(int a, int b)
{
if(a>b) return a;
return b;
}
muchas declaraciones de tiempo y definiciones 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 la variable i y la función max ()
Declaración: "En algún lugar, existe un foo".
Definición: "... y aquí está!"
Diferencia entre declarar y definir con funciones: la declaración de prototipo para una función lo declara, es decir, le informa al compilador acerca de la función: su nombre, tipo de retorno y número y tipo de sus parámetros. El encabezado de la función, seguido del cuerpo de la función, define la función, brindando los detalles de los pasos para realizar la operación de la función.
Ex.
Código:
//Declare
int foo(int);
//Define
int foo(int){
...
}
Con respecto a las variables: Para las variables automáticas y de registro, no hay diferencia entre definición y declaración. El proceso de declarar una variable automática o de registro define el nombre de la variable y asigna la memoria apropiada.
Sin embargo, para variables externas: debido a que la memoria para una variable debe asignarse solo una vez, para garantizar que el acceso a la variable siempre se refiera a la misma celda. Todas las variables deben definirse una vez y solo una vez.
Si se va a usar una variable externa en un archivo diferente al que está definido, se necesita un mecanismo para "conectar" dicho uso con la celda de variable externa definida de forma única que se le asigna. Este proceso de conectar las referencias de la misma variable externa en diferentes archivos, se denomina resolución de las referencias.
Puede definirse y declararse con una declaración de declaración fuera de cualquier función, sin especificador de clase de almacenamiento. Dicha declaración asigna memoria para la variable. También se puede utilizar una declaración de declaración para declarar simplemente un nombre de variable con el especificador de clase de almacenamiento externo al principio de la declaración. Dicha declaración especifica que la variable se define en otro lugar, es decir, la memoria para esta variable se asigna en otro archivo. Por lo tanto, el acceso a una variable externa en un archivo distinto al que está definido es posible si se declara con la palabra clave extern; no se asigna nueva memoria. Dicha declaración le dice al compilador que la variable está definida en otro lugar, y el código se compila con la variable externa que queda sin resolver. La referencia a la variable externa se resuelve durante el proceso de vinculación.
Ex.
Código
//file1.c
extern char stack[10];
extern int stkptr;
....
//file2.c
char stack[10];
int stkptr;
....
Estas declaraciones le dicen al compilador que las variables stack [] y stkptr están definidas en otro lugar, generalmente en algún otro archivo. Si se omitiera la palabra clave extern, las variables se considerarían nuevas y se asignaría memoria para ellas. Recuerde, el acceso a la misma variable externa definida en otro archivo solo es posible si se utiliza la palabra clave extern en la declaración.
Encuentre respuestas similares aquí: Preguntas técnicas de entrevista 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 determinado, introduce un nombre en un ámbito determinado.
Una declaración es una definición a menos que
- 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:
- Definición define un miembro de datos de clase estática,
- Definición define una función miembro no en línea.
Esto va a sonar realmente cursi, pero es la mejor manera en que he podido mantener los términos en mi cabeza:
Declaración: Imagínese a Thomas Jefferson dando un discurso ... "¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡RECUERDE !!!
Definición: imagina un diccionario, estás buscando a Foo y lo que realmente significa.
Hay casos 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 T
es:
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 de borde.
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 una instancia de X<bool>::member
, no cree una instancia de la definición del miembro desde la plantilla principal, sino use la definición que se encuentra en otra parte". Para convertirlo en una definición, debes suministrar un inicializador.
template<>
int X<bool>::member = 1; // definition, belongs into a .cpp file.
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 esto es solo 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 se puede 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 movb de asm.
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 pertenece cierta memoria a cierta variable.
Para entender los sustantivos, concentrémonos primero en los verbos.
declarar - anunciar oficialmente; proclamar
definir - para mostrar o describir (a alguien o algo) clara y completamente
Entonces, cuando declaras algo, simplemente dices lo que es .
// declaration
int sum(int, int);
Esta línea declara una función de C llamada sum
que toma dos argumentos del tipo int
y devuelve un int
. Sin embargo, todavía no puedes usarlo.
Cuando proporciona cómo funciona realmente , esa es la definición de eso.
// definition
int sum(int x, int y)
{
return x + y;
}
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 debe suceder exactamente una vez antes del primer acceso.
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 crea una instancia / implementa este identificador. Es lo que necesita el enlazador para vincular las 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 {};
Una definición puede ser usada 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 algún lugar, entonces el enlazador no sabe a qué vincular las referencias y se queja de los símbolos que faltan. Si define algo más de una vez, entonces el enlazador no sabe con cuál de las definiciones vincular las referencias y se queja sobre los 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é aquí una cita del estándar de C ++.
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:
[Example: [...] struct S { int a; int b; }; // defines S, S::a, and S::b [...] struct S; // declares S —end example
Para resumir: el estándar de C ++ considera la struct x;
para ser una declaración y struct x {};
una definicion (En otras palabras, "declaración de reenvío" es un nombre inapropiado , ya que no hay otras formas de declaraciones de clase en C ++).
Gracias a litb (Johannes Schaub) que descubrió el capítulo y el verso reales en una de sus respuestas.
Una declaración introduce un nombre en el programa; una definición proporciona una descripción única de una entidad (por ejemplo, tipo, instancia y función). Las declaraciones pueden repetirse en un ámbito determinado, introduce un nombre en un ámbito determinado. Debe haber exactamente una definición de cada objeto, función o clase utilizada en un programa de C ++. Una declaración es una definición a menos que:
* 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.
Una definición es una declaración a menos que:
* it defines a static class data member,
* it defines a non-inline member function.
definición significa función real escrita y declaración significa función de declaración simple para, por ejemplo,
void myfunction(); //this is simple declaration
y
void myfunction()
{
some statement;
}
Esta es la definición de mi función funcional.
Declaración:
int a; // this declares the variable ''a'' which is of type ''int''
Así, la declaración asocia la variable con un tipo.
Los siguientes son algunos ejemplos de declaración.
int a;
float b;
double c;
Ahora declaración de función:
int fun(int a,int b);
Note 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 llama a algo como esto
int b=fun(x,y,z);
El compilador lanzará un error diciendo que no existe tal función. Porque no tiene ningún prototipo para esa función.
Note 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 es declarada y definida también. Ya que la llamada a la función viene después de la definición. Ahora ve el siguiente 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 alguna de esas funciones. Así que declaramos la función que informará al compilador.
Definición :
Esta parte de la definición de una función se llama Definición. Dice qué hacer dentro de la función.
void print(int a)
{
printf("%d",a);
}
Ahora con las variables.
int a; //declaration
a=10; //definition
Algunas veces, la declaración y la definición se agrupan en una sola declaración como esta.
int a=10;
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. Un nombre debe ser declarado antes de que pueda ser utilizado.
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 usaremos en el futuro y que puede encontrar una definición más adelante, lo que significa:
traductor asegúrese de que: ¿qué es qué? declaración de medios
y (3) etapa (vinculador) necesita definición para unir las cosas
Linker asegúrese de que: ¿ dónde está qué? significa definición
El concepto de Declaración y Definición formará un escollo cuando esté utilizando 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, las declaraciones se realizan normalmente al principio de una función o página de códigos. En C ++ no es así. Usted puede declarar en el lugar de su elección.
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 estar integrado 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 usen más adelante. Por ejemplo
- Uno puede declarar una variable o matriz heterogénea que no están específicamente definidas.
- 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.
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