Programing

정의와 선언의 차이점은 무엇입니까?

lottogame 2020. 9. 29. 07:12
반응형

정의와 선언의 차이점은 무엇입니까?


둘 다의 의미를 알지 못합니다.


선언 그것을 입력, 개체 또는 함수일, 식별자를 소개하고, 형식을 설명한다. 선언은 컴파일러가 해당 식별자에 대한 참조를 수락하는 데 필요한 것 입니다. 다음은 선언입니다.

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

정의는 실제로 / 구현이 식별자 인스턴스화합니다. 그것은이다 링커 무엇을 필요로하는지 그 실체에 대한 링크를 참조하기 위해. 다음은 위 선언에 해당하는 정의입니다.

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

선언 대신 정의를 사용할 수 있습니다.

식별자는 원하는만큼 자주 선언 할 수 있습니다 . 따라서 다음은 C 및 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);

그러나 정확히 한 번 정의 해야합니다 . 어딘가에서 선언되고 참조 된 것을 정의하는 것을 잊은 경우 링커는 참조를 링크 할 대상을 모르고 누락 된 기호에 대해 불평합니다. 당신이 한 번 이상 무언가를 정의 할 경우, 링커는 모르고 있는 링크 참조에 대한 정의와 중복 문자 메시지를 뿌려줍니다.


클래스 선언C ++ 의 클래스 정의대한 논쟁이 계속 나오기 때문에 (다른 질문에 대한 답변과 주석에서) 여기에 C ++ 표준의 인용문을 붙여 넣겠습니다.
3.1 / 2에서 C ++ 03은 다음과 같이 말합니다.

선언은 [...]이 클래스 이름 선언 [...]이 아닌 한 정의입니다.

3.1 / 3은 몇 가지 예를 제공합니다. 그중 :

[예: [...]
구조체 S {int a; int b; }; // S, S :: a 및 S :: b 정의 [...]
구조체 S; // S 선언
-예제 끝

이를 요약하면 다음 C ++ 표준은 고려 struct x;선언 하고 정의 . (즉, C ++에는 다른 형태의 클래스 선언이 없기 때문에 "앞으로 선언"은 잘못된 이름 입니다.)struct x {};

그의 답변 중 하나에서 실제 장과 구절을 파낸 litb (Johannes Schaub) 에게 감사드립니다 .


C ++ 표준 섹션 3.1에서 :

선언 이전의 선언에 의해 도입 된 번역 단위 또는 redeclares는 이름으로 소개합니다 이름. 선언은 이러한 이름의 해석과 속성을 지정합니다.

다음 단락은 선언 이 정의라는 것을 명시합니다.

... 함수 본문을 지정하지 않고 함수를 선언합니다.

void sqrt(double);  // declares sqrt

... 클래스 정의 내에서 정적 멤버를 선언합니다.

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

... 클래스 이름을 선언합니다.

class Y;

... extern이니셜 라이저 또는 함수 본문없이 키워드를 포함합니다 .

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

... 또는 typedef또는 using문입니다.

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

이제 선언과 정의의 차이점을 이해하는 것이 중요한 이유 인 하나의 정의 규칙 . C ++ 표준의 섹션 3.2.1에서 :

번역 단위는 변수, 함수, 클래스 유형, 열거 유형 또는 템플릿에 대한 정의를 두 개 이상 포함 할 수 없습니다.


선언 : "어딘가에 foo가 있습니다."

정의 : "... 그리고 여기 있습니다!"


C ++에는 흥미로운 경우가 있습니다 (일부는 C에서도 마찬가지입니다). 중히 여기다

T t;

유형에 따라 정의 또는 선언이 될 수 있습니다 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".

C ++에서는 템플릿을 사용할 때 또 다른 예외적 인 경우가 있습니다.

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

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

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

마지막 선언은 정의 아닙니다 . 의 정적 멤버에 대한 명시 적 전문화 선언입니다 X<bool>. "인스턴스화에 관해서 X<bool>::member는 기본 템플릿에서 멤버 정의를 인스턴스화하지 말고 다른 곳에서 찾은 정의를 사용하십시오 "라고 컴파일러에 알립니다 . 정의를 만들려면 이니셜 라이저를 제공해야합니다.

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

선언

선언은 컴파일러에게 프로그램 요소 또는 이름이 존재 함을 알려줍니다. 선언은 프로그램에 하나 이상의 이름을 도입합니다. 선언은 프로그램에서 두 번 이상 발생할 수 있습니다. 따라서 각 컴파일 단위에 대해 클래스, 구조, 열거 유형 및 기타 사용자 정의 유형을 선언 할 수 있습니다.

정의

정의는 이름이 설명하는 코드 또는 데이터를 지정합니다. 이름을 사용하려면 먼저 선언해야합니다.


C99 표준에서 6.7 (5) :

선언은 식별자 집합의 해석 및 속성을 지정합니다. 식별자 정의 는 다음과 같은 식별자에 대한 선언입니다.

  • 객체의 경우 해당 객체에 대해 스토리지를 예약합니다.
  • 함수의 경우 함수 본문을 포함합니다.
  • 열거 형 상수 또는 typedef 이름의 경우 식별자의 (유일한) 선언입니다.

C ++ 표준 3.1 (2)에서 :

선언은 함수의 본문을 지정하지 않고 함수를 선언하지 않는 정의입니다 . extern 지정자 또는 연결 사양을 포함하고 이니셜 라이저도 함수 본문도없고 클래스 선언에서 정적 데이터 멤버를 선언합니다. 클래스 이름 선언 또는 typedef 선언, using-declaration 또는 using-directive입니다.

그런 다음 몇 가지 예가 있습니다.

흥미롭게도 (또는 그렇지 않지만 약간 놀랍습니다) typedef int myint;C99의 정의이지만 C ++의 선언입니다.


wiki.answers.com에서 :

선언이라는 용어는 (C에서) 컴파일러에게 유형, 크기 및 함수 선언의 경우 변수의 매개 변수 유형 및 크기 또는 프로그램의 사용자 정의 유형 또는 함수에 대해 알리는 것을 의미합니다. 선언의 경우 변수를 위해 메모리에 공간이 예약 되지 않습니다 . 그러나 컴파일러는이 유형의 변수가 생성 될 경우 예약 할 공간을 알고 있습니다.

예를 들어 다음은 모든 선언입니다.

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

반면에 정의는 선언이 수행하는 모든 작업 외에도 공간이 메모리에 예약되어 있음을 의미합니다. 다음은 정의의 예입니다. "DEFINITION = DECLARATION + SPACE RESERVATION"이라고 말할 수 있습니다.

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

답변을 참조하십시오 .


C ++ 11 업데이트

C ++ 11과 관련된 답이 보이지 않으므로 여기에 하나가 있습니다.

선언은 a / n을 선언하지 않는 정의입니다 .

  • 불투명 열거 형- enum X : int;
  • 템플릿 매개 변수 -T intemplate<typename T> class MyArray;
  • 매개 변수 선언 -xy inint add(int x, int y);
  • 별칭 선언- using IntVector = std::vector<int>;
  • 정적 주장 선언- static_assert(sizeof(int) == 4, "Yikes!")
  • 속성 선언 (구현 정의)
  • 빈 선언 ;

위 목록에 의해 C ++ 03에서 상속 된 추가 절 :

  • 함수 선언 - 추가int add(int x, int y);
  • 선언 또는 연결 지정자를 포함하는 extern 지정자- extern int a;또는extern "C" { ... };
  • 클래스의 정적 데이터 멤버 -x inclass C { static int x; };
  • 클래스 / 구조체 선언- struct Point;
  • typedef 선언- typedef int Int;
  • 선언 사용- using std::cout;
  • using 지시문- using namespace NS;

템플릿 선언은 선언입니다. 템플릿 선언은 선언이 함수, 클래스 또는 정적 데이터 멤버를 정의하는 경우 정의이기도합니다.

선언과 정의를 구별하는 표준의 예는 그들 사이의 뉘앙스를 이해하는 데 도움이되었다고 생각합니다.

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

정의는 작성된 실제 함수를 의미하고 선언은 간단한 선언 함수를 의미합니다.

void  myfunction(); //this is simple declaration

void myfunction()
{
 some statement;    
}

이것은 myfunction 함수의 정의입니다.


경험 법칙 :

  • 선언은 어떻게 메모리에 변수의 데이터를 해석하는 컴파일러를 알려줍니다. 이는 모든 액세스에 필요합니다.

  • 정의는 변수가 기존 만들 수있는 메모리를 보유하고 있습니다. 이것은 첫 번째 액세스 전에 정확히 한 번 발생해야합니다.


명사를 이해하기 위해 먼저 동사에 집중 해 보겠습니다.

선언 -공식적으로 발표합니다. 선포하다

정의 -(누군가 또는 무언가) 명확하고 완전하게 보여 주거나 설명하기 위해

그래서 무언가를 선언 할 때 그것이 무엇인지 말하면 됩니다 .

// declaration
int sum(int, int);

이 라인은 선언 라는 C 함수 sum형태의 2 개 개의 인수를 취하는 int과를 반환합니다 int. 그러나 아직 사용할 수 없습니다.

실제 작동 방식 을 제공 하는 것이 그 정의입니다.

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

선언 :

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

따라서 선언은 변수를 유형과 연관시킵니다.

다음은 선언의 몇 가지 예입니다.

int a;
float b;
double c;

이제 함수 선언 :

int fun(int a,int b); 

함수 끝에 세미콜론이 있으므로 선언 일뿐임을 알 수 있습니다. 컴파일러는 프로그램의 어딘가에서 해당 프로토 타입으로 함수가 정의 된다는 것을 알고 있습니다 . 이제 컴파일러가 다음과 같은 함수 호출을 받으면

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

컴파일러는 그러한 기능이 없다는 오류를 발생시킵니다. 그 함수에 대한 프로토 타입이 없기 때문입니다.

두 프로그램의 차이점에 유의하십시오.

프로그램 1

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

여기에서 print 함수도 선언하고 정의합니다. 정의 후에 함수 호출이 나오기 때문입니다. 이제 다음 프로그램을 참조하십시오.

프로그램 2

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

함수 호출이 정의보다 우선하므로 컴파일러는 그러한 함수가 있는지 여부를 알아야합니다. 그래서 우리는 컴파일러에 알릴 함수를 선언합니다.

정의 :

This part of defining a function is called Definition. It says what to do inside the function.

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

Now with the variables.

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

Some times declaration and definition are grouped into a single statement like this.

int a=10;

To understand the difference between declaration and definition we need to see the assembly code:

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)

and this is only definition:

ui8 = 5;   |   movb    $0x5,-0x45(%rbp)
i = 5;     |   movl    $0x5,-0x3c(%rbp)
ui32 = 5;  |   movl    $0x5,-0x38(%rbp)
ui64 = 5;  |   movq    $0x5,-0x10(%rbp)
doub = 5;  |   movsd   0x328(%rip),%xmm0        # 0x400a20
               movsd   %xmm0,-0x8(%rbp)

As you can see nothing change.

Declaration is different from definition because it gives information used only by the compiler. For example uint8_t tell the compiler to use asm function movb.

See that:

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

Declaration haven't an equivalent instruction because it is no something to be executed.

Furthermore declaration tells the compiler the scope of the variable.

We can say that declaration is an information used by the compiler to establish the correct use of the variable and for how long some memory belongs to certain variable.


Couldnt you state in the most general terms possible, that a declaration is an identifier in which no storage is allocated and a definition actually allocates storage from a declared identifier?

One interesting thought - a template cannot allocate storage until the class or function is linked with the type information. So is the template identifier a declaration or definition? It should be a declaration since no storage is allocated, and you are simply 'prototyping' the template class or function.


Find similar answers here: Technical Interview Questions in C.

A declaration provides a name to the program; a definition provides a unique description of an entity (e.g. type, instance, and function) within the program. Declarations can be repeated in a given scope, it introduces a name in a given scope.

A declaration is a definition unless:

  • Declaration declares a function without specifying its body,
  • Declaration contains an extern specifier and no initializer or function body,
  • Declaration is the declaration of a static class data member without a class definition,
  • Declaration is a class name definition,

A definition is a declaration unless:

  • Definition defines a static class data member,
  • Definition defines a non-inline member function.

This is going to sound really cheesy, but it's the best way I've been able to keep the terms straight in my head:

Declaration: Picture Thomas Jefferson giving a speech... "I HEREBY DECLARE THAT THIS FOO EXISTS IN THIS SOURCE CODE!!!"

Definition: picture a dictionary, you are looking up Foo and what it actually means.


A declaration presents a symbol name to the compiler. A definition is a declaration that allocates space for the symbol.

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

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

According to the GNU C library manual (http://www.gnu.org/software/libc/manual/html_node/Header-Files.html)

In C, a declaration merely provides information that a function or variable exists and gives its type. For a function declaration, information about the types of its arguments might be provided as well. The purpose of declarations is to allow the compiler to correctly process references to the declared variables and functions. A definition, on the other hand, actually allocates storage for a variable or says what a function does.


The concept of Declaration and Definition will form a pitfall when you are using the extern storage class because your definition will be in some other location and you are declaring the variable in your local code file (page). One difference between C and C++ is that in C you the declarations are done normally at the beginning of a function or code page. In C++ it's not like that. You can declare at a place of your choice.


My favorite example is "int Num = 5" here your variable is 1. defined as int 2. declared as Num and 3. instantiated with a value of five. We

  • Define the type of an object, which may be built-in or a class or struct.
  • Declare the name of an object, so anything with a name has been declared which includes Variables, Funtions, etc.

A class or struct allows you to change how objects will be defined when it is later used. For example

  • One may declare a heterogeneous variable or array which are not specifically defined.
  • Using an offset in C++ you may define an object which does not have a declared name.

When we learn programming these two terms are often confused because we often do both at the same time.


Stages of an executable generation:

(1) pre-processor -> (2) translator/compiler -> (3) linker

In stage 2 (translator/compiler), declaration statements in our code tell to the compiler that these things we are going to use in future and you can find definition later, meaning is :

translator make sure that : what is what ? means declaration

and (3) stage (linker) needs definition to bind the things

Linker make sure that : where is what ? means definition


Declaration means give name and type to a variable (in case of variable declaration), eg:

int i;

or give name,return type and parameter(s) type to a function without body(in case of function declaration), eg:

int max(int, int);

whereas definition means assign value to a variable (in case of variable definition), eg:

i = 20;

or provide/add body(functionality) to a function is called function definition, eg:

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

many time declaration and definition can be done together as:

int i=20;

and:

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

In above cases we define and declare variable i and function max().


There are some very clear definitions sprinkled throughout K&R (2nd edition); it helps to put them in one place and read them as one:

"Definition" refers to the place where the variable is created or assigned storage; "declaration" refers to the places where the nature of the variable is stated but no storage is allocated. [p. 33]

...

It is important to distinguish between the declaration of an external variable and its definition. A declaration announces the properties of a variable (primarily its type); a definition also causes storage to be set aside. If the lines

int sp;
double val[MAXVAL]

appear outside of any function, they define the external variables sp and val, cause storage to be set aside, and also serve as the declaration for the rest of that source file.

On the other hand, the lines

extern int sp;
extern double val[];

declare for the rest of the source file that sp is an int and that val is a double array (whose size is determined elsewhere), but they do not create the variables or reserve storage for them.

There must be only one definition of an external variable among all the files that make up the source program. ... Array sizes must be specified with the definition, but are optional with an extern declaration. [pp. 80-81]

...

Declarations specify the interpretation given to each identifier; they do not necessarily reserve storage associated with the identifier. Declarations that reserve storage are called definitions. [p. 210]

참고URL : https://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration

반응형