Pregunta

El significado de los dos me escapa.

¿Fue útil?

Solución

Una declaración introduce un identificador y describe su tipo, ya sea un tipo, objeto o función. Una declaración es lo que necesita el compilador 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 puede ser declarado tantas veces como lo 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 estar definido 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 enlazador no sabe cuál de las definiciones para vincular referencias y se queja de símbolos duplicados.


Dado que el debate sobre qué es una clase declaración frente a una clase definición en C ++ sigue apareciendo (en respuestas y comentarios a otras preguntas), pegaré un cita del estándar 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:

[Example: [...]
struct S { int a; int b; }; // defines S, S::a, and S::b [...]
struct S; // declares S
—end example

En resumen: el estándar C ++ considera que struct x; es una declaración y struct x {}; una definición . (En otras palabras, & Quot; declaración hacia adelante & Quot; 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 versículo en uno de sus respuestas

Otros consejos

De la sección 3.1 estándar de C ++:

  

Una declaración introduce nombres en una unidad de traducción o redeclara nombres introducidos por anteriores   Declaraciones 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 la función & # 8217; s body:

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 una declaración typedef o using.

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

Ahora, por la gran razón por la cual es importante comprender 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.

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

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

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

T t;

Puede ser una definición o una declaración, según el tipo T que sea:

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 fue no una definición. Es la declaración de una especialización explícita del miembro estático de X<bool>. Le dice al compilador: & Quot; Si se trata de instanciar X<bool>::member, entonces no cree una instancia de la definición del miembro de la plantilla primaria, sino que use la definición que se encuentra en otro lugar & Quot ;. Para que sea una definición, debe proporcionar un inicializador

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

Declaración

  

Las declaraciones le dicen al compilador que un   El elemento o nombre del programa existe. 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, clases, estructuras,   tipos enumerados y otros   los tipos definidos por el usuario pueden declararse para   cada unidad de compilación.

Definición

  

Las definiciones especifican qué código o datos   El nombre describe. Un nombre debe ser   declarado antes de que pueda usarse.

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 de la 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 una estática miembro de datos en una declaración de clase, es una 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 ++.

De wiki.answers.com:

El término declaración significa (en C) que le está informando al compilador sobre el tipo, el 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. El espacio No está reservado en la memoria para cualquier 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 & Quot; DEFINICIÓN = DECLARACIÓN + RESERVA DE ESPACIO & Quot; Los siguientes son ejemplos de definición:

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

ver Respuestas .

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 una / n:

  • enumeración opaca - enum X : int;
  • parámetro de plantilla - T en template<typename T> class MyArray;
  • declaración de parámetros - x y y en int 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 función - agregar en extern int a;
  • especificador externo que contiene declaración o un especificador de enlace - extern "C" { ... }; o class C { static int x; };
  • miembro de datos estáticos en una clase - x en struct Point;
  • declaración de clase / estructura - typedef int Int;
  • declaración typedef - using std::cout;
  • usando declaración - using namespace NS;
  • usando la directiva - <=>

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

definición significa función real escrita & amp; declaración significa simple declarar función por ej.

void  myfunction(); //this is simple declaration

y

void myfunction()
{
 some statement;    
}

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

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.

Declaración:

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

Por lo tanto, 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); 

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 también se declara y define. Dado que la llamada a la función viene después de la definición. Ahora vea 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 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);
}

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;

Para entender a los nombres, vamos a centrarnos en los verbos de la primera.

declarar - para anunciar oficialmente;proclamar

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

Así, cuando se dice algo, que acaba de decirle lo que es.

// declaration
int sum(int, int);

Esta línea declara una función de C llama sum que toma dos argumentos de tipo int y devuelve un int.Sin embargo, no se puede usar todavía.

Cuando usted proporciona cómo funciona realmente, que es la definición de la misma.

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

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.

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

Encuentre respuestas similares aquí: Preguntas técnicas de la 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 dado, 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 no hay inicializador ni 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,
  • 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 ... & "; DECLARO QUE ESTE FOO EXISTE EN ESTE CÓDIGO DE FUENTE !!! &";

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

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

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

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

int i;

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

int max(int, int);

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

i = 20;

o proporcionar/add cuerpo(funcionalidad) a una función se llama función de la definición, por ejemplo:

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

el tiempo de muchos declaración y definición pueden hacer juntos como:

int i=20;

y:

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

En los casos anteriores, podemos definir y declarar la variable i y function max().

El concepto de Declaración y Definición formará un obstáculo 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.

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.
  • Declarar 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 luego se usen. 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.

Etapas de una generación ejecutable:

  

(1) preprocesador - > (2) traductor / compilador - & Gt; (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 utilizar en el futuro y puede encontrar la definición más adelante, lo que significa:

  

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

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

  

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top