초기화, 정의, 변수 선언의 차이점


78

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


1
초기화는 변수를위한 것입니다. 정의는 본문을 정의하는 함수에도 적용 할 수 있습니다.
FKaria 2014

그래서 당신은 변수를 의미합니까, 맞습니다.
Tony

답변:


99

선언

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

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;

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

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


14
정답이 아닙니다 : int x;정의이자 선언입니다.
문헌 : Angew는 더 이상 자랑 SO의없는

2
@Angew, 감사 합니다 . 더 완전한 정의를 추가했습니다 .
Shoe

나는 OP가 그의 포스트에서 언급 한 질문이 정의와 선언에 꽤 잘 대답한다고 생각합니다. 그러나 원래 질문은 So does it mean definition equals declaration plus initialization.
Tahlil

@Tahlil, 결론을 추가했습니다. 알려 주셔서 감사합니다.
Shoe

3
@Tony 나는 생각한다 (내가 잘못하면 누군가 나를 고쳐주세요) 'extern int x'는 그것을 선언으로 만듭니다. 즉 그 정의는 다른 곳에서 찾을 수 있습니다. 'int x'는 실제로 'int x = 5'와 같이 초기화하지 않는 한 임의의 쓰레기 값으로 지정되지만 실제로 정의합니다.
brat

41

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

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 ++가 아닐 것입니다.) 초기화에는 정적 수명이있는 변수의 제로 초기화, 기본 생성자 및 표시되는 내용이 포함됩니다. (혼란을 더하기 위해 : C에서 초기화는 변수가 처음 할당 될 수 있습니다. 예를 들어 "초기화되지 않은 변수의 값 가져 오기"와 같은 명령문에서.이 중 일부가 안으로 들어간다고해도 놀라지 않을 것입니다. C ++.)
James Kanze

아, 그리고 C ++가 선언에서 초기화 사양을 허용하는 특별한 경우도 있습니다.
James Kanze 2014

1
@JamesKanze : 이러한 목적을 위해 매우 간단하게 유지하기로 결정했습니다.
궤도의 Lightness Races

6

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

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

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

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

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

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

C11 6.7.9.8-10 기준 :

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

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

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

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

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

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


C ++에서 초기화는 크게 다릅니다. (C는 또한 수명이 정적 오브젝트 제로 초기화 등가를 갖는다.)
제임스 간제

@JamesKanze : 예, 안타깝게도이 질문에는 C와 C ++ 모두 태그가 지정되어 있습니다.이 질문은 서로 다른 점에서는별로 도움이되지 않습니다.
Crowman 2014

아주. 호환되는 유형의 경우 C ++ 의 의도 (적어도 원래)는 C에서와 동일하게 작동한다는 것입니다. 사실 언어 자체가 호환되는 모든 경우에 여전히 동일하게 작동한다고 생각합니다. 그러나이 동작을 정의하는 데 사용되는 표현은 상당히 다릅니다.
James Kanze 2014

1

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

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

 void helloWorld(); //declaration or Prototype.

 void helloWorld()
 {
    std::cout << "Hello World\n";
 } 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.