반응형

변수 선언을 해야 메모리에 등록을 하든지 참조를 하든지 할 것이다. 하지만 그 변수 선언에 대해 본인은 다 알지 못한다고 본다. 앞으로 익숙하든 생소하든 선언자에 쭉 탐구해보기로 하겠다.

 

MSDN - 자체 번역 + 자체 예제(해보고 올린다는 뜻 + 따로 표시를 할 것임)

 

 

 

 

선언 및 정의 (C++)

선언 및 정의 (C++)Declarations and Definitions (C++) 이 문서의 내용 --> 선언은 프로그램에서 하는 이름, 변수, 네임 스페이스, 함수 및 클래스의 이름 예입니다.Declarations introduce names in a program, for example the names of variables, namespaces, functions and classes. 또한, 선언은 형식 정보뿐만 아니라 선언되는 개체의 다른

docs.microsoft.com

 

선언은 프로그램에서 하는 이름, 변수, 네임 스페이스, 함수 및 클래스의 이름 예입니다. 또한, 선언은 형식 정보뿐만 아니라 선언되는 개체의 다른 특성도 지정합니다. 이름은 먼저 선언해야 사용할 수 있습니다. C++에서는 이름이 선언되는 지점에 따라 이름이 컴파일러에 표시되는지 여부가 달라집니다. 나중에 컴파일 단위에서 선언된 함수 또는 클래스를 참조할 수 없습니다.(이 제한을 해결하려면 정방향선언(forward declarations)을 사용할 수 있습니다.)

정의는 이름을 설명 하는 코드 또는 데이터를 지정합니다. 선언할 항목을 위한 저장소 공간을 할당하려면 컴파일러에 정의가 있어야 합니다.

 

 

선언

선언은 프로그램에 하나 이상의 이름을 제공합니다. 선언은 프로그램에서 두 번 이상 발생할 수 있습니다. 따라서 클래스, 구조체, 열거 형식 및 다른 사용자 정의 형식이 각 컴파일 단위에 대해 선언될 수 있습니다. 이 여러 선언에 대한 제약 조건은 모든 선언이 동일해야 한다는 것입니다. 다음 경우를 제외하고 선언은 정의 역할도 합니다.

  1. 함수 선언이 프로토타입(함수 본문이 없는 함수 선언)일 경우입니다.

  2. extern 지정자를 포함하지만 초기화 변수(개체 및 변수) 또는 함수 본문 (함수)이 존재하지 않는 경우. 이것은 정의가 반드시 현재 변환 단위에 있지 않으며, 외부에 링크된 이름을 제공하는 것을 나타냅니다.

  3. 선언이 클래스 선언 내의 정적 데이터 멤버입니다. (static)

    정적 클래스 데이터 멤버는 클래스의 모든 개체가 공유하는 개별 변수이므로 클래스 선언 외부에서 정의 및 초기화되어야 합니다. (클래스 및 클래스 멤버에 대 한 자세한 내용은 참조 하세요. 클래스.)

  4. 선언이 class T;와 같은 정의가 뒤따르지 않는 클래스 이름 선언입니다.

  5. typedef 문입니다.

 

 

 

다음은 정의와 선언을 같이하는 예제입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Declare and define int variables i and j.
int i;
int j = 10;
 
// Declare enumeration suits.
enum suits { Spades = 1, Clubs, Hearts, Diamonds };
 
// Declare class CheckBox.
class CheckBox : public Control
{
public:
            Boolean IsChecked();
    virtual int     ChangeState() = 0;
};
 
 

 

  • 1번줄에서는 i와 j int형을 각각 쓰레기 값과 10으로 정의 및 선언이 되었다.
  • 6번줄에서는 suits 열거형을 {값}의 내용으로 정의 및 선언을 하였다.
  • 8번줄에서는 CheckBox 클래스를 내부 함수와 상속받는 클래스를 정의 및 선언을 하였다.

 

다음은 정의없이 선언만 하는 예제이다.

 

1
2
extern int i;
char *strchr( const char *Str, const char Target );
 

 

 

  • 이름은 선언자 바로 뒤, 초기화값 앞에서 선언됩니다. 자세한 내용은 선언 지점을 참고하세요.
  • 정의는 스코프(Scope) 내에서 이루어집니다. 스코프는 이름의 선언과 개체가 정의된 기간을 가시적으로 통제합니다. 어떻게 정의와 스코프의 규칙이 이루어지는 것에 대한 내용은 스코프를 참고하세요.
  • 객체 정의는 또한 스토리지클래스(Storage classes)에 설명된 extern 정의를 포함하지 않았다면, 선언이기도 합니다. 함수 정의 역시 프로토타입(prototype)이 아니라면 선언이기도 합니다. 프로토타입(prototype)이란 함수 본문 없이 함수의 머리부분(Function Header - 번역 힘듦ㅡ.ㅡ;; 대충 [void A()] 딱 이부분... 근데 알잖여)만 있는 것을 뜻합니다. 개체의 선언은 해당 개체의 저장소가 할당되고 적절한 초기화가 수행됩니다.

정의(필자 왈 - 예외적인 경우 포함ㅇㅇ)

정의는 개체 또는 변수, 함수, 클래스 또는 열거자들에 대해 고유한 사양(specification - 의역 -> (값))이어야 합니다. 정의가 고유해야, 프로그램에서는 지정된 프로그램 요소에 대한 정의가 하나만 포함될 수 있습니다. 선언과 정의 간에 다 대 일 대응이 있을 수 있습니다. 프로그램 요소가 선언되지만 정의되지는 않는 두 가지 경우가 있습니다.

  1. 함수가 선언되지만 함수 호출 또는 함수의 주소를 사용하는 식으로 참조되지 않습니다.

  2. 한 클래스가 클래스 정의부분에서 알려지지 않는 방식으로만 사용됩니다. 그러나 클래스는 선언되어야 합니다. 다음 코드에서는 이러한 경우를 보여 줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
class WindowCounter;   // Forward declaration; no definition
 
class Window
{
   // Definition of WindowCounter not required
   static WindowCounter windowCounter;
};
 
int main()
{
}
 
 

 

 

2번줄에서 클래스가 정의 없이 전방선언 되어있다. -> 이걸 알려지지 않은 방식이라 써놈(in a way that does not require its definition be known)

7번줄에서 해당 클래스를 static(정적) 선언을 하였지만 해당 클래스이 정의는 어떤 정의를 요구하지 않는다.

 

따라서 초기화 과정(정의하는)이 없다.

 

 

완전 헷갈리고 있었다. 이참에 확실히 해야한다.

int a = 0; 중 int a는 선언부 이고, = 0 은 정의부이다.

참고 내용은 아래다.

 

C++의 선언 지점

선언자 바로 뒤, 이니셜라이저 앞(선택 사항)에서 이름이 선언된다고 간주합니다. 선언자에 대한 자세한 내용은 선언 및 정의를 참조하세요.

다음 예제를 참고해 보세요.

 

1
2
3
4
5
6
7
// compile with: /W1
double dVar = 7.0;
int main()
{
   double dVar = dVar;   // C4700
}
 
 

선언 시점이 초기화 후일 경우 로컬 dVar 이 전역 변수 dVar의 값인 7.0으로 초기화됩니다. 그러나 그런 경우는 아니므로 dVar이 정의되지 않은 값으로 초기화됩니다.

 

-> 즉, 정의되지 않은 dVar을 dVar에 넣겠다는 경우다. 흠... 터진다. 과연 어디를 고쳐야 하는지 보겠다.
일단 이 예제의 문제점은 전역변수와 로컬변수 간 이름이 같다는 것이다. 이럴 경우 스코프 규칙에 따라 외부 변수가 숨겨지는 현상이 발생한다. 때문에 정의하려는 변수가 전역변수임을 알리기 위해서 [::]를 붙여야 한다. 다음은 해당 예제를 실행될 수 있도록 고친 결과이다.

 

1
2
3
4
5
double dVar = 7.0;
int main()
{
    double dVar = ::dVar;   // C4700
}
 
 

 

 

 

 

선언자 개요

선언자는 개체 또는 함수 이름을 지정하는 선언의 구성 요소입니다. 선언자는 명명된 객체가 개체, 포인터, 참조 또는 배열인지 여부도 지정합니다. 선언자는 기본 형식을 지정하지는 않지만, 포인터, 참조 및 배열과 같은 파생 형식을 지정하는 기본 형식의 형식 정보를 수정합니다. 함수에 적용되는 선언자는 형식 지정자와 함께 작동하여 개체, 포인터 또는 참조가 될 함수의 반환 형식을 완전히 지정합니다. (선언 및 정의에 설명 된 지정자는 형식 및 저장소 클래스와 같은 속성을 전달합니다. Microsoft 전용 한정자에서 설명된 한정자는 선언자를 수정합니다.) 다음 그림에서는 MyFunction의 전체 선언과 선언의 구성 요소를 보여 줍니다.

지정자(Modifier), 한정자(Specifier), 선언자(Declarator)

 

 

 

 

Microsoft 전용

대부분의 Microsoft 확장 키워드를 파생 형식을 형성하기 위한 한정자로 사용할 수 있습니다. 해당 키워드는 지정자나 선언자가 아닙니다. (참조 Microsoft 전용 한정자.)

 

Microsoft 전용 종료

선언자는 선택적인 지정자 목록 뒤의 선언 구문에 나타납니다. 이러한 지정자는 나오는 선언합니다. 선언에는 둘 이상의 선언자가 포함될 수 있지만 각 선언자는 이름 하나만 선언합니다.

 

다음 예제에서는 전체 선언을 만들기 위해 지정자와 선언자를 결합하는 방법을 보여줍니다.

1
const char *pch, ch;
 

 

앞의 선언에서 키워드의 const  char 지정자의 목록을 확인합니다. 두 가지 선언자인 *pch  ch가 나열됩니다. 여러 엔터티를 선언하는 선언은 형식 지정자 다음에 쉼표로 구분된 선언자 목록이 이어지고 세미콜론으로 끝납니다.

 

 

간단한 개체에 대 한 선언 자

int 또는 double과 같은 단순 개체의 선언자는 단순히 그러한 개체의 이름이며 괄호를 선택적으로 사용합니다.

int i; // declarator is i

int (i); // declarator is (i)

 

 

 

 

---------------------------------------------------------------

아래 예제부터는 특히나 더 헷갈릴 가능성이 있는 코드이기에 꼭 숙지하기 바란다.

 

 

포인터, 참조 및 배열에 대한 선언자

  • 이름 앞에 포인터 연산자가 삽입된 개체는 포인터 또는 참조가 됩니다. * 연산자는 포인터로서 이름을 정의하고, & 연산자는 참조로서 선언합니다.
1
2
3
int *i; // declarator is *i
int **i; // declarator is **i;
int &= x; // declaratory is &i
 

 

자세한 내용은에서 확인할 수 있습니다. const 및 volatile 포인터.

 

예제 설명_

1번줄 - char 형을 가리키는 const pointer 형

2번줄 - const char 형을 가리키는 pointer 형

3번줄 - const char 형을 가리키는 conster pointer 형

 

 

  • 클래스 또는 구조체 멤버의 포인터는 적절한 중첩 이름 지정자를 사용하여 선언됩니다.
1
2
3
int X::* pIntMember;
int ::X::* pIntMember; // the initial :: specifies X is in global scope
char Outer::Inner::* pIntMember; // pointer to char in a nested class
 

 

예제 설명_

1번줄 - 스코프 내 혹은 전역범위에 존재하는 클래스(구조체) X 멤버 변수의 int 포인터 형

2번줄 - 전역범위에 존재하는 클래스(구조체) X 멤버 변수의 int 포인터 형

3번줄 - Outer 내 이너클래스(이너구조체) Inner 멤버 변수의 int 포인터 형

 

 

int X::* 형??

1
2
3
4
5
6
7
8
9
10
class X
{
public:
    int a, b, c;
};
 
int main()
{
    int X::* pIntMember = &X::a;
}
 
 

int X::* - 클래스 내부에 있는 int 형 변수의 포인터를 선언한다.

 

 

 

  • 이름 뒤에 선택적인 상수 식을 묶는 대괄호는 개체를 배열로 만듭니다. 대괄호를 연속으로 사용하면 배열에 추가 차원이 선언됩니다.
1
2
3
4
int i[5]; // array with five elements of type int numbered from 0 to 4
int i[]; // array of unknown size
char *s[4]; // array of pointers to char
int i[2][2]; // two dimensional array
 
 

예제 설명_

1번줄 - 0에서 4가지의 int형 숫자를 가진 5원소짜리 배열

2번줄 - 사이즈가 정해지지 않은 배열

3번줄 - char형 포인터 들의 배열

4번줄 - 2차원 배열

 

 

 

 

함수에 대한 선언자

  • 인수 목록이 포함된 괄호는 이름 뒤에서 함수를 선언하는 데 사용됩니다. 다음은 int 형 반환 형식과 세 가지 인수 int를 가진 함수를 선언합니다.
1
int f(int a, int b, int c);
 
  • 함수의 포인터 및 참조는 아래와 같이 함수 이름 앞에 포인터 또는 참조 연산자를 추가하여 선언됩니다. 괄호는 보통 선택적으로 사용되며, 함수의 포인터를, 포인터를 반환하는 함수와 구별할 때 필요합니다.
     
1
2
3
int (*pf)(int); // pointer to function returning int
int *f(int i); // function returning pointer to int
int (&pf)(int); // reference to function
 

예제 설명_
1번줄 - int를 반환하는 함수의 포인터

2번줄 - int 포인터를 반환하는 함수

3번줄 - 함수의 참조형

 

 

 

  • 멤버 함수의 포인터는 중첩 이름 지정자로 구별됩니다.
1
2
int (X::* pmf)(); // pointer to member function of X returning int
int* (X::* pmf)(); // pointer to member function returning pointer to int
 

예제 설명_

1번줄 - 클래스 X내 int를 반환하는 멤버함수의 포인터

2번줄 - 클래스 X내 int 포인터를 반환하는 멤버함수의 포인터

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class X
{
public:
    int a, b, c;
    int func1();
    int* func2();
};
 
int main()
{
    int (X:: * pmf)(); // pointer to member function of X returning int
    int* (X:: * pmf2)(); // pointer to member function returning pointer to int
 
    pmf = &X::func1;
    pmf2 = &X::func2;
}
 
 

 

자체 예제_

14번, 15번 줄에서 해당 함수를 받는 모습을 보여준다.

 

참고 - 멤버에 대한 포인터

 

 

 

같은 선언에 놓인 함수와 객체

  • 함수 및 개체는 다음과 같이 동일한 선언으로 선언될 수 있습니다.
1
int i, *j, f(int k);  // int, pointer to int, function returning int
 

 

  • 다음 경우에는 이 구문은 일부 상황에서 잘못 인식될 수 있습니다.
1
int* i, f(int k);  // pointer to int, function returning int (not int*)
 

 

-> i는 int 포인터를 나타내지만 함수 f는 int 포인터가 아닌 int를 반환한다.

마치 int 포인터 int 포인터를 반환하는 함수의 선언처럼 보일 수 있지만, 그렇지 않습니다. [*]는 함수 f선언의 일부가 아닌 i 선언의 일부이기 때문입니다.

 

 

 

Typedef과 선언자 구문 단순화

기술적으로 typedef 키워드 혹은 typedef와 괄호의 조합하며 사용하는 것이 더 나은 방법입니다. 다음 함수 포인터의 배열 선언을 살펴보십시오.

 

1
2
3
4
5
6
7
//  Function returning type int that takes one
//   argument of type char *.
typedef int (*PIFN)( char * );
//  Declare an array of 7 pointers to functions
//   returning int and taking one argument of type
//   char *.
PIFN pifnDispatchArray[7];
 

 

예제 설명_

1, 2번줄 - 전역범위에서 char* 형을 매개변수로 받고 int를 반환하는 함수의 포인터 typedef 선언

4, 5, 6번줄 - 전역범위에서 char* 형을 매개변수로 받고 int를 반환하는 함수의 포인터를 7개 가진 배열 선ㄹ

 

 

 

typedef 없이 동일한 선언을 작성할 수 있습니다. 하지만 이러한 작업은 복잡한 가시성 때문에 잠재적인 오류에 노출되어 있습니다..

1
int ( *pifnDispatchArray[7] )( char * );
 

typedef 정의에 대한 자세한 내용은 Aliases 및 typedef을 참조하세요.

 

 

 

단일 기본 형식의 포인터, 참조, 배열은 다음과 같이 쉼표로 구분된 단일 선언으로 결합할 수 있습니다.

1
int a, *b, c[5], **d, &e=a;
 

더 복잡한 선언자 구문

  • 함수의 포인터 배열, 배열의 포인터 등과 같은 개체를 지정하기 위해 포인터, 참조, 배열 및 함수 선언자를 결합할 수 있습니다.

  • 포인터 선언자 구문은 다음 재귀 문법에서 완벽하게 설명됩니다.

  • declarator[선언자]는 다음 중 하나로 정의됩니다.

    1. 식별자 -> (이름)
    2. 정규화된 이름
    3. declarator ( argument-list ) [cv-qualfiers] [exception-spec] -> (함수)
    4. declarator [ [ constant-expression ] ] -> (배열)
    5. 포인터-연산자(pointer-operator) 선언자 -> (포인터)
    6. (선언자)
  •  포인터 연산자 중 하나입니다.

    1. * [cv-qualifiers]
    2. & [cv-qualifiers] ::nested-name-specifier * [cv-qualifiers]

선언자에 선언자를 포함시킬 수 있기 때문에, 위의 규칙을 사용하여 포인터의 배열이나 함수 포인터의 배열을 반환하는 함수 같은 더욱 복잡한 파생 형식을 생성할 수 있습니다. 생성의 각 단계의 만들려면, 기본 데이터 형식을 표시하는 식별자로 시작하여 이전의 식을 declarator로 사용해 위의 구문 규칙을 적용해야 합니다. 구문 규칙을 적용하는 순서는 영어로 식을 만드는 방식의 반대입니다. 배열 또는 함수 식에 포인터 연산자 구문 규칙을 적용하는 경우 아래 표의 마지막 행과 같이 배열이나 함수를 가리키는 포인터를 원하면 괄호를 사용하십시오

 

다음 예제에서는 "int의 10개 포인터 배열의 포인터"의 생성을 보여줍니다. -> 누적되는 방식이다

 

구두(실전) 표현 - 누적 선언자 적용되는 구문 [위의 경우 참고]
  i 1
포인터로 *i 5
10개짜리 배열로 (*i)[10] 4
포인터로 *((*i)[10]) 6, 5

여러 포인터, 참조, 배열 또는 함수 한정자가 사용될 때 선언자는 매우 복잡해질 수 있습니다. 더 복잡 한 선언 자 해석에서는 더 복잡한 선언자 구문을 읽는 방법에 대해 설명합니다. 이 주제는 C와 C ++ 모두에 적용 할 수 있지만 C++에서는 포인터를 나타내는 데 *가 사용되는 곳이면 MyClass :: *와 같은 수식 된 이름을 사용하여 클래스 멤버에 대한 포인터를 지정할 수 있습니다.

 

 

 

 

더 복잡한 선언자 해석

선언자를 괄호로 묶어 "복합 선언자"의 특정 해석을 지정할 수 있습니다. 복합 선언자는 둘 이상의 배열, 포인터 또는 함수 한정자로 한정된 식별자입니다. 배열, 포인터 및 함수 한정자의 다양한 조합을 단일 식별자에 적용할 수 있습니다. 일반적으로 typedef를 사용하여 선언을 단순화할 수 있습니다. Typedef 선언을 참조하세요.

복합 선언자를 해석할 때 대괄호와 괄호(즉, 식별자 오른쪽의 한정자)는 별표(즉, 식별자 왼쪽의 한정자)보다 우선합니다. 대괄호와 괄호는 우선 순위가 동일하고 왼쪽에서 오른쪽으로 연결됩니다. 선언자가 완전히 해석된 후 형식 지정자가 마지막 단계로 적용됩니다. 괄호를 사용하여 기본 연결 순서를 재정의하고 특정 해석을 적용할 수 있습니다. 그러나 식별자 이름 자체는 괄호로 묶지 마십시오. 괄호로 묶으면 매개 변수 목록으로 잘못 해석될 수 있습니다.

 

복합 선언자를 해석하는 간단한 방법은 다음 4단계를 사용하여 "내부에서 외부로" 읽는 것입니다.

  1. 식별자에서 시작하고 대괄호 또는 괄호(있는 경우)의 오른쪽을 바로 확인합니다.

  2. 이러한 대괄호 또는 괄호를 해석한 다음 별표의 왼쪽을 확인합니다.

  3. 어떤 단계에서든 오른쪽 괄호를 발견하면 뒤로 돌아가서 괄호 안의 모든 항목에 규칙 1 및 2를 적용합니다.

  4. 형식 지정자를 적용합니다.

1
2
3
char **(*var)() )[10];
 ^   ^  ^ ^ ^   ^    ^
 7   6  4 2 1   3    5
 

이 예제에서 단계는 순서대로 번호가 매겨지고 다음과 같이 해석될 수 있습니다.

  1. var 식별자는 다음으로 선언됩니다.

  2. 다음에 대한 포인터

  3. 다음을 반환하는 함수

  4. 다음에 대한 포인터

  5. 다음과 같은 10개 요소의 배열

  6. 다음에 대한 포인터

  7. char 

예제

다음 예제에서는 다른 복합 선언을 보여 주고 괄호가 선언의 의미에 미치는 영향을 나타냅니다.

  

 

  • 배열 한정자는 포인터 한정자보다 우선 순위가 높으므로 var은 배열로 선언됩니다. 포인터 한정자는 배열 요소의 형식에 적용되므로 배열 요소는 int 값에 대한 포인터입니다.
1
int *var[5]; /* Array of pointers to int values */
 

 

  • 아래 선언에서 var에 대한 괄호는 배열 한정자보다 포인터 한정자에 보다 높은 우선 순위를 부여하고, var은 int 값이 5개인 배열에 대한 포인터로 선언됩니다.
1
int (*var)[5]; /* Pointer to array of int values */
 

 

 

  • 함수 한정자도 포인터 한정자보다 우선 순위가 높기 때문에 var에 대한 이 선언은 var을 long 값에 대한 포인터를 반환하는 함수로 선언합니다. 함수는 두 개의 long 값을 인수로 사용하도록 선언됩니다.

1
long *var( longlong ); /* Function returning pointer to long */
 

 

 

 

  • 아래 예제는 앞의 예제와 유사합니다. 괄호는 포인터 한정자에 함수 한정자보다 높은 우선 순위를 부여하고, var은 long 값을 반환하는 함수에 대한 포인터로 선언됩니다. 여기에서도 함수는 두 가지 long 인수를 사용합니다.
1
long (*var)( longlong ); /* Pointer to function returning long */
 

 

 

  • 배열의 요소가 함수일 수는 없지만 이 선언은 함수에 대한 포인터 배열을 선언하는 방법을 대신 보여줍니다. 이 예제에서 var은 두 멤버가 포함된 구조체를 반환하는 함수에 대한 포인터 5개의 배열로 선언됩니다. 함수에 대한 인수는 동일한 구조체 형식 both를 사용하는 두 구조체로 선언됩니다. *var[5] 주위에는 괄호가 필요합니다. 괄호 없이 이 다음의 예제와 같이 함수 배열을 선언하는 것은 잘못된 시도입니다.
1
2
3
4
5
struct both       /* Array of pointers to functions */
{                 /*   returning structures         */
    int a;
    char b;
} ( *var[5] )( struct both, struct both );
 
1
2
/* ILLEGAL */
struct both *var[5](struct both, struct both);
 

 

 

  • 다음 문은 포인터의 배열을 선언합니다.
1
unsigned int *(* const *name[5][10] ) ( void );
 

name 배열에는 다차원 배열로 구성된 50개의 요소가 있습니다. 요소는 상수인 포인터에 대한 포인터입니다. 이 상수 포인터는 매개 변수가 없고 부호 없는 형식에 대한 포인터를 반환하는 함수를 가리킵니다.

 

 

 

  • 다음 예제는 double 값이 세 개인 배열에 대한 포인터를 반환하는 함수입니다.
1
double ( *var( double (*)[3] ) )[3];
 

이 선언에서 배열을 반환하는 함수가 잘못되었으므로 함수는 배열에 대한 포인터를 반환합니다. 여기서 var은 double 값이 세 개인 배열에 대한 포인터를 반환하는 함수로 선언됩니다. var 함수는 인수를 하나 사용합니다. 인수는 반환 값과 마찬가지로 double 값이 세 개인 배열에 대한 포인터입니다. 인수 형식은 복합 추상 선언자에서 제공됩니다. 인수 형식에서 별표 주위에 괄호가 필요합니다. 괄호가 없으면 인수 형식이 double 값에 대한 세 포인터의 배열이 됩니다. 추상 선언자에 대한 설명과 예제는 추상 선언자를 참조하세요.

 

1
2
3
4
5
union sign         /* Array of arrays of pointers */
{                  /* to pointers to unions       */
     int x;
     unsigned y;
**var[5][5];
 
 

위의 예제와 같이 포인터는 다른 포인터를 가리킬 수 있으며 배열에는 배열이 요소로 포함될 수 있습니다. 여기서 var은 요소가 5개인 배열입니다. 각 요소는 멤버가 두 개인 공용 구조체에 대한 포인터에 대한 포인터의 배열(요소가 5개임)입니다.

1
2
union sign *(*var[5])[5]; /* Array of pointers to arrays
                             of pointers to unions        */
 

이 예제에서는 괄호의 위치에 따라 선언의 의미가 어떻게 바뀌는지를 보여 줍니다. 이 예제에서 var은 공용 구조체에 대한 포인터의 배열(요소가 5개임)에 대한 포인터의 배열(요소가 5개임)입니다. typedef를 사용하여 복합 선언을 방지하는 방법에 대한 예제를 보려면 Typedef 선언을 참조하세요.

반응형

'C++' 카테고리의 다른 글

const*, constexpr**  (0) 2019.12.25
Scope - 범위  (0) 2019.12.25
연산자 static_cast + const_cast + reinterpret_cast  (0) 2019.12.25
키워드 - cast, casting + 연산자 dynamic_cast + 예외 bad_cast + type-id, typeinfo  (0) 2019.12.24
자료형  (0) 2019.12.24
Posted by Kestone Black Box
,