Qual é a diferença entre uma definição e uma declaração?


858

O significado de ambos me escapa.


91
@ Lasse: não é verdade. A definição define e declara ;-)
Steve Jessop

13
Sinceramente, tive muitos problemas para aprender qual era qual, então não achei os nomes óbvios. Não tive problemas com os significados, apenas quais nomes associar com os significados.
22615 David Thornley

6
Ainda assim, não é uma pergunta duplicada, pois isso pergunta sobre C / C ++, enquanto essa outra pergunta é feita sobre todos os idiomas, ou nenhum, em geral. Ele possui apenas respostas duplicadas (já que nessa outra pergunta, algumas respostas optaram por ignorar todo o idioma, exceto C e / ou C ++).
Steve Jessop

5
@ DavidThornley Eu uso este truque: uma definição fornece uma descrição mais refinada de uma determinada variável ou função. Para lembrar disso, lembro que o meio da palavra "definição" tem uma semelhança com a palavra "mais fina". :)
Marco Leogrande

4
Incrível quanta porcaria existe nessa questão. Apenas mostra o quanto essa linguagem é mal compreendida e como esses mal-entendidos são rotineiramente propagados . É triste mesmo.
Lightness Races in Orbit

Respostas:


858

Uma declaração introduz um identificador e descreve seu tipo, seja um tipo, objeto ou função. Uma declaração é o que o compilador precisa para aceitar referências a esse identificador. Estas são declarações:

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

Uma definição realmente instancia / implementa esse identificador. É o que o vinculador precisa para vincular referências a essas entidades. Estas são definições correspondentes às declarações acima:

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

Uma definição pode ser usada no lugar de uma declaração.

Um identificador pode ser declarado quantas vezes você desejar. Portanto, o seguinte é legal em C e 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);

No entanto, ele deve ser definido exatamente uma vez. Se você esquecer de definir algo que foi declarado e referenciado em algum lugar, o vinculador não sabe ao que vincular referências e reclama sobre a falta de símbolos. Se você definir algo mais de uma vez, o vinculador não saberá a quais definições vincular referências e queixas sobre símbolos duplicados.


Como o debate sobre o que é uma declaração de classe versus uma definição de classe em C ++ continua aparecendo (em respostas e comentários para outras perguntas), colarei uma citação do padrão C ++ aqui.
Em 3.1 / 2, o C ++ 03 diz:

Uma declaração é uma definição, a menos que seja [...] uma declaração de nome de classe [...].

3.1 / 3 dá alguns exemplos. Dentre elas:

[Exemplo: [...]
struct S {int a; int b; }; // define S, S :: ae S :: b [...]
struct S; // declara S
- por exemplo

Resumindo: O padrão C ++ considera struct x;uma declaração e struct x {};uma definição . (Em outras palavras, "declaração direta" é um nome impróprio , pois não há outras formas de declaração de classe em C ++.)

Agradecimentos a Litb (Johannes Schaub), que desenterrou o capítulo e o verso em uma de suas respostas.


2
@ desconhecido: ou seu compilador está quebrado, pois você copiou incorretamente o código do sbi. Por exemplo, 6.7.2 (2) no N1124: "Todas as declarações que se referem ao mesmo objeto ou função devem ter tipo compatível; caso contrário, o comportamento é indefinido."
Steve Jessop

4
@ Brian: "int externo;" diz que eu sou um int em algum lugar, não se preocupe. "int i;" significa que i é um int e seu endereço e escopo são determinados aqui.
David Thornley

12
@ Brian: Você está errado. extern int ié uma declaração, uma vez que apenas introduz / especifica i. Você pode ter quantos extern int iem cada unidade de compilação quiser. int i, no entanto, é uma definição. Denota o espaço para o número inteiro estar nesta unidade de conversão e aconselha o vinculador a vincular todas as referências a iessa entidade. Se você tiver mais ou menos do que exatamente uma dessas definições, o vinculador irá reclamar.
sbi 11/09/09

4
@Brian int i;no escopo arquivo / global ou escopo da função é uma definição tanto em C quanto em C ++. Em C, porque aloca armazenamento, e em C ++, porque não possui o especificador externo ou uma especificação de ligação. Isso equivale à mesma coisa, como diz o sbi: nos dois casos, esta declaração especifica o objeto ao qual todas as referências a "i" nesse escopo devem ser vinculadas.
Steve Jessop

4
@ desconhecido, cuidado, você não pode redefinir os membros no escopo da classe : struct A { double f(int, double); double f(int, double); };inválido, é claro. É permitido em outro lugar embora. Há alguns lugares onde você pode declarar as coisas, mas não define, também: void f() { void g(); }válido, mas não o seguinte: void f() { void g() { } };. O que é uma definição e que declaração tem regras sutis quando se trata de modelos - cuidado! +1 para uma boa resposta.
Johannes Schaub - litb 11/09/09

168

Na seção 3.1 do padrão C ++:

Uma declaração introduz nomes em uma unidade de tradução ou redefine nomes introduzidos por declarações anteriores. Uma declaração especifica a interpretação e os atributos desses nomes.

O próximo parágrafo declara (ênfase minha) que uma declaração é uma definição, a menos que ...

... declara uma função sem especificar o corpo da função:

void sqrt(double);  // declares sqrt

... declara um membro estático dentro de uma definição de classe:

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

... declara um nome de classe:

class Y;

... contém a externpalavra - chave sem um inicializador ou corpo de função:

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

... ou é uma declaração typedefou using.

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

Agora, pela grande razão pela qual é importante entender a diferença entre uma declaração e definição: a Regra de Uma Definição . Na seção 3.2.1 do padrão C ++:

Nenhuma unidade de tradução deve conter mais de uma definição de qualquer variável, função, tipo de classe, tipo de enumeração ou modelo.


"declara um membro estático dentro de uma definição de classe" - Isso é verdade mesmo se o membro estático for inicializado, correto? Podemos fazer o exemplo struct x {static int b = 3; };?
precisa saber é o seguinte

@RJFalconer Você está correto; a inicialização não transforma necessariamente uma declaração em uma definição (ao contrário do que se poderia esperar; certamente achei isso surpreendente). Sua modificação no exemplo é realmente ilegal, a menos que btambém seja declarada const. Consulte stackoverflow.com/a/3536513/1858225 e daniweb.com/software-development/cpp/threads/140739/… .
Kyle Strand

1
Isso é interessante para mim. De acordo com sua resposta, parece que em C ++, uma declaração também é uma definição (com exceções), enquanto que no padrão C é formulada de outra perspectiva (C99, seção 6.7, Declarações): "Uma definição de identificador é uma declaração para esse identificador que: [seguida por critérios para diferentes casos] ". Diferentes maneiras de encarar isso, suponho. :)
Victor Zamanian

A declaração é para o compilador aceitar um nome (para informar ao compilador que o nome é legal, o nome é introduzido com intenção e não um erro de digitação). Definição é onde um nome e seu conteúdo estão associados. A definição é usada pelo vinculador para vincular uma referência de nome ao conteúdo do nome.
11006 Gab Gabo

137

Declaração: "Em algum lugar, existe um foo".

Definição: "... e aqui está!"


3
A declaração é para o compilador aceitar um nome (para informar ao compilador que o nome é legal, o nome é introduzido com intenção e não um erro de digitação). Definição é onde um nome e seu conteúdo estão associados. A definição é usada pelo vinculador para vincular uma referência de nome ao conteúdo do nome.
11246 Gab Gab

46

Existem casos interessantes em C ++ (alguns deles também em C). Considerar

T t;

Pode ser uma definição ou declaração, dependendo do tipo T:

typedef void T();
T t; // declaration of function "t"

struct X { 
  T t; // declaration of function "t".
};

typedef int T;
T t; // definition of object "t".

No C ++, ao usar modelos, há outro caso de borda.

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

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

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

A última declaração não era uma definição. É a declaração de uma especialização explícita do membro estático de X<bool>. Ele diz ao compilador: "Se for para instanciar X<bool>::member, não instancie a definição do membro a partir do modelo primário, mas use a definição encontrada em outro lugar". Para fazer uma definição, você precisa fornecer um inicializador

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

35

Declaração

As declarações informam ao compilador que existe um elemento ou nome de programa. Uma declaração introduz um ou mais nomes em um programa. As declarações podem ocorrer mais de uma vez em um programa. Portanto, classes, estruturas, tipos enumerados e outros tipos definidos pelo usuário podem ser declarados para cada unidade de compilação.

Definição

As definições especificam quais códigos ou dados o nome descreve. Um nome deve ser declarado antes de poder ser usado.


Não é possível definir classes e enumerações em cada unidade de compilação? Pelo menos eu coloco definições de classe nos meus cabeçalhos e as incluo por toda parte. Er, class foo {}; é uma definição de classe , não é?
sbi 11/09/09

1
Sim. No entanto, "classe foo;" é uma declaração. Diz ao compilador que foo é uma classe. "classe foo {};" é uma definição. Diz ao compilador exatamente que tipo de classe é foo.
23915 David Thornley

1
A exceção são nomes de membros da classe que podem ser usados ​​antes de serem declarados.
Johannes Schaub - litb

1
Sim, foi o que eu quis dizer. Então você pode fazer o seguinte: struct foo {void b () {f (); } void f (); }, f é visível mesmo que ainda não tenha sido declarado. O seguinte também funciona: struct foo {void b (int = bar ()); typedef int bar; } ;. É visível antes da declaração em "todos os corpos de função, argumentos padrão, construtores e inicializadores de ctor". Não no tipo de retorno :(
Johannes Schaub - litb 11/09/09

1
@ litb: Não é visível antes da declaração, é apenas que o uso do identificador é movido para trás da declaração. Sim, eu sei, o efeito é o mesmo para muitos casos. Mas não para todos os casos, e é por isso que acho que devemos usar a explicação precisa. - Opa, espera. É visível nos argumentos padrão? Bem, isso certamente causa estragos no meu entendimento. Droga! <
pouts

22

Do padrão C99, 6,7 (5):

Uma declaração especifica a interpretação e os atributos de um conjunto de identificadores. Uma definição de um identificador é uma declaração para esse identificador que:

  • para um objeto, faz com que o armazenamento seja reservado para esse objeto;
  • para uma função, inclui o corpo da função;
  • para uma constante de enumeração ou nome de tipo de typed, é a declaração (única) do identificador.

No padrão C ++, 3.1 (2):

Uma declaração é uma definição, a menos que declare uma função sem especificar o corpo da função, contenha o especificador externo ou uma especificação de ligação e nem um inicializador nem um corpo da função, declare um membro de dados estático em uma declaração de classe, é um declaração de nome de classe ou é uma declaração typedef, uma declaração de uso ou uma diretiva de uso.

Depois, existem alguns exemplos.

Tão interessante (ou não, mas estou um pouco surpreso com isso) typedef int myint;é uma definição em C99, mas apenas uma declaração em C ++.


@onebyone: Com relação ao typedef, isso não significa que ele pode ser repetido em C ++, mas não em C99?
sbi 11/09/09

Foi isso que me surpreendeu e, no que diz respeito a uma única unidade de tradução, sim, há essa diferença. Mas claramente um typedef pode ser repetido em C99 em diferentes unidades de tradução. C não possui uma "regra de definição única" explícita como C ++, portanto, as regras que possui apenas permitem. O C ++ escolheu alterá-lo para uma declaração, mas também a regra de definição única lista a que tipos de coisas se aplica e typedefs não é um deles. Portanto, repetições seriam permitidas em C ++ sob o ODR como está redigido, mesmo que um typedef fosse uma definição. Parece desnecessariamente exigente.
Steve Jessop

... mas acho que essa lista no ODR realmente lista todas as coisas das quais é possível ter definições. Nesse caso, a lista é realmente redundante e existe apenas para ser útil.
Steve Jessop

O que a definição de ODR do std diz sobre as definições de classe? Eles precisam ser repetidos.
sbi 11/09/09

2
@sbi: ODR diz "(1) Nenhuma unidade de tradução deve conter mais de uma definição de qualquer ... tipo de classe" e "(5) Pode haver mais de uma definição de um tipo de classe ... em um programa, desde que cada definição aparece em uma unidade de tradução diferente "e, em seguida, alguns requisitos extras que equivalem a" as definições são as mesmas ".
Steve Jessop

17

Do wiki.answers.com:

O termo declaração significa (em C) que você está dizendo ao compilador sobre tipo, tamanho e, no caso de declaração de função, tipo e tamanho de seus parâmetros de qualquer variável ou tipo ou função definida pelo usuário em seu programa. Nenhum espaço é reservado na memória para qualquer variável em caso de declaração. No entanto, o compilador sabe quanto espaço reservar, caso uma variável desse tipo seja criada.

por exemplo, a seguir estão todas as declarações:

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

A definição, por outro lado, significa que, além de tudo o que a declaração faz, o espaço também é reservado na memória. Você pode dizer "DEFINIÇÃO = DECLARAÇÃO + RESERVA DE ESPAÇO" a seguir são exemplos de definição:

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

veja Respostas .


3
Isso também está errado (embora muito mais próximo que os outros): struct foo {};é uma definição , não uma declaração. Uma declaração de fooseria struct foo;. A partir disso, o compilador não sabe quanto espaço reservar para os fooobjetos.
SBI

1
@ Marcin: O sbi está dizendo que "o compilador sabe quanto espaço reservar no caso de uma variável desse tipo ser criada" nem sempre é verdadeira. struct foo;é uma declaração, mas não informa ao compilador o tamanho de foo. Eu acrescentaria que struct _tagExample { int a; int b; };é uma definição. Portanto, neste contexto, é enganoso chamá-lo de declaração. Claro que é uma, já que todas as definições são declarações, mas você parece sugerir que não é uma definição. É uma definição de _tagExample.
Steve Jessop

1
@ Marc Gil: O que significa que o wiki "Answers" nem sempre é preciso. Eu tenho que votar aqui por desinformação aqui.
David Thornley

1
Aprendemos que o que o adatapost citado é verdadeiro, mas não responde (IMO) realmente à pergunta. O que Marcin citou é falso. A citação dos padrões é verdadeira e responde à pergunta, mas é muito difícil de entender.
Steve Jessop

1
@ David Thornley - não é um problema :) É disso que trata este site. Nós selecionar e verificar informações.
Marcin Gil

13

Atualização do C ++ 11

Como não vejo uma resposta pertinente ao C ++ 11, aqui está uma.

Uma declaração é uma definição, a menos que declare a / n:

  • enum opaco - enum X : int;
  • parâmetro de modelo - T intemplate<typename T> class MyArray;
  • declaração de parâmetro - x e y emint add(int x, int y);
  • declaração de alias - using IntVector = std::vector<int>;
  • declaração de declaração estática - static_assert(sizeof(int) == 4, "Yikes!")
  • declaração de atributo (definida pela implementação)
  • declaração vazia ;

Cláusulas adicionais herdadas do C ++ 03 pela lista acima:

  • declaração da função - adicionar emint add(int x, int y);
  • especificador externo contendo declaração ou especificador de ligação - extern int a;ouextern "C" { ... };
  • membro de dados estáticos em uma classe - x emclass C { static int x; };
  • declaração de classe / estrutura - struct Point;
  • declaração typedef - typedef int Int;
  • usando declaração - using std::cout;
  • usando diretiva - using namespace NS;

Uma declaração de modelo é uma declaração. Uma declaração de modelo também é uma definição se sua declaração define uma função, uma classe ou um membro de dados estático.

Exemplos do padrão que diferencia entre declaração e definição que achei úteis para entender as nuances entre eles:

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

6

Definição:

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

A definição associa a variável a um tipo e aloca memória, enquanto a declaração apenas especifica o tipo, mas não aloca memória. A declaração é mais útil quando você deseja consultar a variável antes da definição.

* Não confunda definição com inicialização. Ambos são diferentes, a inicialização dá valor à variável. Veja o exemplo acima.

A seguir estão alguns exemplos de definição.

int a;
float b;
double c;

Agora , declaração de função:

int fun(int a,int b); 

Observe o ponto-e-vírgula no final da função, por isso diz que é apenas uma declaração. O compilador sabe que em algum lugar do programa essa função será definida com esse protótipo. Agora, se o compilador receber uma chamada de função, algo como isto

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

O compilador lançará um erro dizendo que não existe essa função. Porque ele não possui nenhum protótipo para essa função.

Observe a diferença entre dois programas.

Programa 1

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

Neste, a função de impressão é declarada e definida também. Como a chamada de função está vindo após a definição. Agora veja o 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);
 }

É essencial porque a chamada de função precede a definição, portanto o compilador deve saber se existe alguma função. Então, declaramos a função que informará o compilador.

Definição:

Essa parte da definição de uma função é chamada de Definição. Diz o que fazer dentro da função.

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

2
int a; //declaration; a=10; //definitionIsso está completamente errado. Ao falar sobre objetos de duração de armazenamento automático (objetos declarados dentro de uma definição de função que não são declarados com outro especificador de classe de armazenamento como extern), essas são sempre definições.
Joey Pabalinas

A principal diferença a entender é que uma declaração está dizendo "existe algo em algum lugar que possui essas características (tipo etc.)", enquanto uma definição está dizendo "Estou declarando uma coisa com essas características e também a instanto aqui como bem." Como você não pode encaminhar declarar objetos de duração de armazenamento automático como esse, eles sempre serão definições.
Joey Pabalinas

Exceto por alguns casos estranhos de cantos digitados que eu sempre esqueço, uma regra geral é que Todas as definições são declarações. Pense nisso; Quando você está instanciando algo, também precisa informar ao compilador que essa coisa existe e quais são suas características corretas?
Joey Pabalinas

Atualizada a resposta conforme seu primeiro comentário. no entanto, eu não concordo com este comentário "quando você está instanciando algo, você também precisa informar ao compilador que essa coisa existe". Nem sempre especificamos o tipo de lhs ao instanciar. Ex: a = 10. Não estamos especificando nenhuma "característica" de um aqui.
SRIDHARAN 31/01

4

definição significa função real escrita e declaração significa função de declaração simples para, por exemplo

void  myfunction(); //this is simple declaration

e

void myfunction()
{
 some statement;    
}

esta é a definição da função myfunction


1
E quanto a tipos e objetos?
SBI

4

Regra prática:

  • Uma declaração informa ao compilador como interpretar os dados da variável na memória. Isso é necessário para todo acesso.

  • Uma definição reserva a memória para tornar a variável existente. Isso precisa acontecer exatamente uma vez antes do primeiro acesso.


2
Isso vale apenas para objetos. E quanto a tipos e funções?
Lightness Races in Orbit

4

Para entender os substantivos, vamos nos concentrar primeiro nos verbos.

declarar - anunciar oficialmente; proclamar

define - para mostrar ou descrever (alguém ou algo) clara e completamente

Então, quando você declara algo, basta dizer o que é .

// declaration
int sum(int, int);

Essa linha declara uma função C chamada sumque recebe dois argumentos do tipo inte retorna an int. No entanto, você não pode usá-lo ainda.

Quando você fornece como realmente funciona , essa é a definição.

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

3

Para entender a diferença entre declaração e definição, precisamos ver o código do assembly:

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)

e isso é apenas definição:

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 você pode ver, nada muda.

A declaração é diferente da definição porque fornece informações usadas apenas pelo compilador. Por exemplo, uint8_t diz ao compilador para usar a função asm movb.

Veja que:

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

A declaração não possui uma instrução equivalente, porque não é algo a ser executado.

Além disso, a declaração informa ao compilador o escopo da variável.

Podemos dizer que a declaração é uma informação usada pelo compilador para estabelecer o uso correto da variável e por quanto tempo alguma memória pertence a determinada variável.


2

Não foi possível declarar, nos termos mais gerais possíveis, que uma declaração é um identificador no qual nenhum armazenamento é alocado e uma definição realmente aloca armazenamento de um identificador declarado?

Um pensamento interessante - um modelo não pode alocar armazenamento até que a classe ou função esteja vinculada às informações de tipo. Então, o identificador de modelo é uma declaração ou definição? Deve ser uma declaração, já que nenhum armazenamento é alocado e você está simplesmente 'criando um protótipo' da classe ou função do modelo.


1
Sua definição não está errada, mas "definição de armazenamento" sempre parece estranha quando se trata de definições de função. Em relação aos modelos: Esta template<class T> struct foo;é uma declaração de modelo , e assim é template<class T> void f();. As definições de modelo espelham as definições de classe / função da mesma maneira. (Observe que o nome de um modelo não é um tipo ou nome de função . Um lugar onde você pode ver isso é quando não é possível transmitir um modelo como parâmetro de tipo de outro modelo. Se você deseja passar modelos em vez de tipos, precisa de parâmetros de modelo. )
sbi 11/09/09

Concordou que 'definição de armazenamento' é incômoda, especialmente em relação às definições de função. A declaração é int foo () e a definição é int foo () {// algum código aqui ..}. Eu geralmente precisam envolver minha pequena cérebro com conceitos estou familiarizado - 'armazenamento' é uma forma de mantê-lo em linha reta pelo menos para mim ... :)

2

Encontrar respostas semelhantes aqui: Perguntas entrevista técnica em C .

Uma declaração fornece um nome para o programa; uma definição fornece uma descrição exclusiva de uma entidade (por exemplo, tipo, instância e função) dentro do programa. As declarações podem ser repetidas em um determinado escopo; ele introduz um nome em um determinado escopo.

Uma declaração é uma definição, a menos que:

  • Declaração declara uma função sem especificar seu corpo,
  • A declaração contém um especificador externo e nenhum inicializador ou corpo de função,
  • Declaração é a declaração de um membro de dados de classe estática sem uma definição de classe,
  • Declaração é uma definição de nome de classe,

Uma definição é uma declaração, a menos que:

  • Definição define um membro de dados de classe estática,
  • Definição define uma função de membro não embutido.

1

Isso vai parecer muito extravagante, mas é a melhor maneira de manter os termos em mente:

Declaração: Imagine Thomas Jefferson fazendo um discurso ... "DECLARO QUE ESTE FOO EXISTE NESTE CÓDIGO DE ORIGEM !!!"

Definição: imagine um dicionário, você está procurando Foo e o que realmente significa.


1

Uma declaração apresenta um nome de símbolo para o compilador. Uma definição é uma declaração que aloca espaço para o símbolo.

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

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

1

De acordo com o manual da biblioteca GNU C ( http://www.gnu.org/software/libc/manual/html_node/Header-Files.html )

Em C, uma declaração apenas fornece informações de que uma função ou variável existe e fornece seu tipo. Para uma declaração de função, informações sobre os tipos de seus argumentos também podem ser fornecidas. O objetivo das declarações é permitir que o compilador processe corretamente as referências às variáveis ​​e funções declaradas. Uma definição, por outro lado, na verdade aloca armazenamento para uma variável ou diz o que uma função faz.


0

O conceito de Declaração e Definição formará uma armadilha quando você estiver usando a classe de armazenamento externo, porque sua definição estará em outro local e você estará declarando a variável no seu arquivo de código local (página). Uma diferença entre C e C ++ é que, em C, as declarações são feitas normalmente no início de uma função ou página de código. Em C ++, não é assim. Você pode declarar em um local de sua escolha.


1
Isso confunde declaração com definição e é totalmente errado.
Sb

0

Meu exemplo favorito é "int Num = 5" aqui sua variável é 1. definida como int 2. declarada como Num e 3. instanciada com um valor de cinco. Nós

  • Defina o tipo de um objeto, que pode ser incorporado ou uma classe ou estrutura.
  • Declare o nome de um objeto, para que qualquer coisa com um nome tenha sido declarada, incluindo Variáveis, Funções, etc.

Uma classe ou estrutura permite alterar como os objetos serão definidos quando usados ​​posteriormente. Por exemplo

  • Pode-se declarar uma variável ou matriz heterogênea que não são definidas especificamente.
  • Usando um deslocamento em C ++, você pode definir um objeto que não possui um nome declarado.

Quando aprendemos a programar, esses dois termos geralmente são confundidos, porque geralmente fazemos as duas coisas ao mesmo tempo.


Não entendo por que tantas pessoas votaram na resposta do sbi. Promovi a resposta por bjhend, que foi bastante boa, concisa, precisa e muito mais oportuna que a minha. Fiquei triste ao ver que fui a primeira pessoa a fazê-lo em 4 anos.
Jason K.

0

Etapas de uma geração executável:

(1) pré-processador -> (2) tradutor / compilador -> (3) vinculador

No estágio 2 (tradutor / compilador), as declarações de declaração em nosso código informam ao compilador que essas coisas vamos usar no futuro e você poderá encontrar a definição posteriormente, o que significa:

tradutor certifique-se de que: o que é o quê? significa declaração

e (3) estágio (vinculador) precisa de definição para vincular as coisas

O Linker garante: onde está o quê? significa definição


0

Existem algumas definições muito claras espalhadas por todo o K&R (2ª edição); ajuda colocá-los em um único lugar e lê-los como um:

"Definição" refere-se ao local onde a variável é criada ou atribuída armazenamento; "declaração" refere-se aos locais onde a natureza da variável é declarada, mas nenhum armazenamento é alocado. [p. 33]

...

É importante distinguir entre a declaração de uma variável externa e sua definição . Uma declaração anuncia as propriedades de uma variável (principalmente seu tipo); uma definição também faz com que o armazenamento seja reservado. Se as linhas

int sp;
double val[MAXVAL]

aparecem fora de qualquer função, eles definem as variáveis ​​externas spe valfazem com que o armazenamento seja separado e também servem como declaração para o restante desse arquivo de origem.

Por outro lado, as linhas

extern int sp;
extern double val[];

declare para o restante do arquivo de origem que spé inte que valé uma doublematriz (cujo tamanho é determinado em outro lugar), mas eles não criam as variáveis ​​ou reservam armazenamento para elas.

Deve haver apenas uma definição de variável externa entre todos os arquivos que compõem o programa de origem. ... Os tamanhos de matriz devem ser especificados com a definição, mas são opcionais com umextern declaração. [pp. 80-81]

...

As declarações especificam a interpretação dada a cada identificador; eles não reservam necessariamente armazenamento associado ao identificador. As declarações que reservam armazenamento são chamadas de definições . [p. 210]


-1

Declaração significa dar nome e tipo a uma variável (no caso de declaração de variável), por exemplo:

int i;

ou forneça o nome, digite o tipo de retorno e o tipo de parâmetro (s) para uma função sem corpo (no caso de declaração de função), por exemplo:

int max(int, int);

Considerando que definição significa atribuir valor a uma variável (no caso de definição de variável), por exemplo:

i = 20;

ou fornecer / adicionar corpo (funcionalidade) a uma função é chamado de definição de função, por exemplo:

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

muitas declarações e definições de tempo podem ser feitas juntas como:

int i=20;

e:

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

Nos casos acima, definimos e declaramos variáveis ie function max().


a média real da definição se atribuir valor / corpo para uma variável / função enquanto meio de declaração fornecer nome, tipo a uma variável / função
Puneet Purohit

Você pode definir algo sem atribuir um valor a ele.
Lightness Races in Orbit

1
Assim:int x;
Lightness Races in Orbit

sua declaração de variável não x seu defination
Puneet Purohit

2
Não, são os dois. Você está confundindo definição com inicialização.
Lightness Races in Orbit
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.