초기화, 정의, 변수 선언의 차이점 질문을 읽은 후 선언과 정의의 차이점을

질문을 읽은 후 선언과 정의의 차이점을 알고 있습니다. 그렇다면 정의가 선언과 초기화를 더한 것과 같음을 의미합니까?



답변

선언

일반적으로 선언은 프로그램에 새 이름을 도입하는 것을 의미합니다. 예를 들어 “서명”을 설명하여 새 함수를 선언 할 수 있습니다 .

void xyz();

또는 불완전한 유형을 선언하십시오.

class klass;
struct ztruct;

마지막으로 객체를 선언하는 방법은 다음과 같습니다.

int x;

C ++ 표준에서는 §3.1 / 1에서 다음과 같이 설명됩니다.

선언 (Clause 7)은 하나 이상의 이름을 번역 단위에 도입하거나 이전 선언에서 도입 한 이름을 재 선언 할 수 있습니다.

정의

정의는 이전에 선언 된 이름의 정의입니다 (또는 정의와 선언 둘 다일 수 있음). 예를 들면 :

int x;
void xyz() {...}
class klass {...};
struct ztruct {...};
enum { x, y, z };

특히 C ++ 표준은 §3.1 / 1에서 다음과 같이 정의합니다.

선언은 함수의 본문 (8.4)을 지정하지 않고 함수를 선언하지 않는 한 정의이며, 외부 지정자 (7.1.1) 또는 연결 사양 25 (7.5)을 포함하며 이니셜 라이저도 함수 본문도 포함하지 않습니다. 클래스 정의 (9.2, 9.4)의 정적 데이터 멤버, 클래스 이름 선언 (9.1), opaque-enum-declaration (7.2), 템플릿 매개 변수 (14.1), 매개 변수- 함수 정의의 선언자가 아닌 함수 선언자에서 선언 (8.3.5) 또는 typedef 선언 (7.1.3), 별칭 선언 (7.1.3), 사용 선언 (7.3. 3), static_assert-declaration (Clause 7), attribute- 선언 (Clause 7), 빈 선언 (Clause 7) 또는 using-directive (7.3.4).

초기화

초기화는 생성시 값의 “할당”을 의미합니다. 유형의 일반 객체 T의 경우 대개 다음과 같은 형식입니다.

T x = i;

그러나 C ++에서는 다음과 같을 수 있습니다.

T x(i);

또는:

T x {i};

C ++ 11로.

결론

그렇다면 정의가 선언과 초기화를 더한 것과 같음을 의미합니까?

때에 따라 다르지. 당신이 말하는 것에 대해. 예를 들어 객체에 대해 이야기하는 경우 :

int x;

이것은 초기화가없는 정의입니다. 대신 다음은 초기화가있는 정의입니다.

int x = 0;

특정 상황에서 “초기화”, “정의”및 “선언”에 대해 말하는 것은 이치에 맞지 않습니다. 예를 들어 함수에 대해 이야기하는 경우 초기화 는 그다지 의미가 없습니다.

따라서 대답은 아니오입니다 . 정의는 자동으로 선언과 초기화를 의미하지 않습니다.


답변

선언은 “이것이 어딘가에 존재한다”라고 말한다 :

int foo();       // function
extern int bar;  // variable
struct T
{
   static int baz;  // static member variable
};

정의는 “이것이 여기에 존재합니다. 기억하십시오”라고 말합니다.

int foo() {}     // function
int bar;         // variable
int T::baz;      // static member variable

초기화는 객체 정의 시점에서 선택 사항이며 “여기에이 항목의 초기 값이 있습니다.”라고 말합니다.

int bar = 0;     // variable
int T::baz = 42; // static member variable

때로는 선언 시점에서 가능합니다.

struct T
{
   static int baz = 42;
};

… 그러나 그것은 더 복잡한 기능으로 들어가고 있습니다.


답변

C의 경우, 최소한 C11 6.7.5에 따라 :

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

  • 객체의 경우 해당 객체에 대해 스토리지를 예약합니다.

  • 함수의 경우 함수 본문을 포함합니다.

  • 열거 형 상수의 경우 식별자의 (유일한) 선언입니다.

  • typedef 이름의 경우 식별자의 첫 번째 (또는 유일한) 선언입니다.

C11 6.7.9.8-10 기준 :

이니셜 라이저는 객체에 저장된 초기 값을 지정합니다. 자동 저장 기능이있는 객체가 명시 적으로 초기화되지 않은 경우 해당 값은 확정되지 않습니다.

따라서 광범위하게 말하면 선언은 식별자를 소개하고 이에 대한 정보를 제공합니다. 변수의 경우 정의는 해당 변수에 대한 저장소를 할당하는 선언입니다.

초기화는 객체에 저장 될 초기 값의 사양으로, 처음 명시 적으로 값을 할당 할 때와 반드시 동일하지는 않습니다 . 변수는 명시 적으로 값을 제공하는지 여부에 관계없이 정의 할 때 값을 갖습니다. 명시 적으로 값을 지정하지 않고 변수에 자동 저장이 있으면 초기 값이 있지만 해당 값은 확정되지 않습니다. 정적 저장소가있는 경우 유형에 따라 암시 적으로 초기화됩니다 (예 : 포인터 유형이 널 포인터로 초기화되고 산술 유형이 0으로 초기화 됨).

따라서 다음과 같이 초기 값을 지정하지 않고 자동 변수를 정의하는 경우 :

int myfunc(void) {
    int myvar;
    ...

당신은 그것을 정의하고 있지만 (정의는 선언이기 때문에 선언하기도하지만) 초기화하지는 않습니다. 따라서 정의는 선언과 초기화를 더한 것과 같지 않습니다.


답변

“정의가 선언과 초기화를 더한 것과 같다는 뜻입니까?”

반드시 다음과 같이 변수를 초기화하지 않고 선언 할 수 있습니다.

 void helloWorld(); //declaration or Prototype.

 void helloWorld()
 {
    std::cout << "Hello World\n";
 }