더 복잡한 선언자 해석Interpreting More Complex Declarators

선언자를 괄호로 묶어 "복합 선언자"의 특정 해석을 지정할 수 있습니다.You can enclose any declarator in parentheses to specify a particular interpretation of a "complex declarator." 복합 선언자는 둘 이상의 배열, 포인터 또는 함수 한정자로 한정된 식별자입니다.A complex declarator is an identifier qualified by more than one array, pointer, or function modifier. 배열, 포인터 및 함수 한정자의 다양한 조합을 단일 식별자에 적용할 수 있습니다.You can apply various combinations of array, pointer, and function modifiers to a single identifier. 일반적으로 typedef를 사용하여 선언을 단순화할 수 있습니다.Generally typedef may be used to simplify declarations. Typedef 선언을 참조하세요.See Typedef Declarations.

복합 선언자를 해석할 때 대괄호와 괄호(즉, 식별자 오른쪽의 한정자)는 별표(즉, 식별자 왼쪽의 한정자)보다 우선합니다.In interpreting complex declarators, brackets and parentheses (that is, modifiers to the right of the identifier) take precedence over asterisks (that is, modifiers to the left of the identifier). 대괄호와 괄호는 우선 순위가 동일하고 왼쪽에서 오른쪽으로 연결됩니다.Brackets and parentheses have the same precedence and associate from left to right. 선언자가 완전히 해석된 후 형식 지정자가 마지막 단계로 적용됩니다.After the declarator has been fully interpreted, the type specifier is applied as the last step. 괄호를 사용하여 기본 연결 순서를 재정의하고 특정 해석을 적용할 수 있습니다.By using parentheses you can override the default association order and force a particular interpretation. 그러나 식별자 이름 자체는 괄호로 묶지 마십시오.Never use parentheses, however, around an identifier name by itself. 괄호로 묶으면 매개 변수 목록으로 잘못 해석될 수 있습니다.This could be misinterpreted as a parameter list.

복합 선언자를 해석하는 간단한 방법은 다음 4단계를 사용하여 "내부에서 외부로" 읽는 것입니다.A simple way to interpret complex declarators is to read them "from the inside out," using the following four steps:

  1. 식별자에서 시작하고 대괄호 또는 괄호(있는 경우)의 오른쪽을 바로 확인합니다.Start with the identifier and look directly to the right for brackets or parentheses (if any).

  2. 이러한 대괄호 또는 괄호를 해석한 다음 별표의 왼쪽을 확인합니다.Interpret these brackets or parentheses, then look to the left for asterisks.

  3. 어떤 단계에서든 오른쪽 괄호를 발견하면 뒤로 돌아가서 괄호 안의 모든 항목에 규칙 1 및 2를 적용합니다.If you encounter a right parenthesis at any stage, go back and apply rules 1 and 2 to everything within the parentheses.

  4. 형식 지정자를 적용합니다.Apply the type specifier.

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

    이 예제에서 단계는 순서대로 번호가 매겨지고 다음과 같이 해석될 수 있습니다.In this example, the steps are numbered in order and can be interpreted as follows:

  5. var 식별자는 다음으로 선언됩니다.The identifier var is declared as

  6. 다음에 대한 포인터a pointer to

  7. 다음을 반환하는 함수a function returning

  8. 다음에 대한 포인터a pointer to

  9. 다음과 같은 10개 요소의 배열an array of 10 elements, which are

  10. 다음에 대한 포인터pointers to

  11. charchar values.

예제Examples

다음 예제에서는 다른 복합 선언을 보여 주고 괄호가 선언의 의미에 미치는 영향을 나타냅니다.The following examples illustrate other complex declarations and show how parentheses can affect the meaning of a declaration.

int *var[5]; /* Array of pointers to int values */  

배열 한정자는 포인터 한정자보다 우선 순위가 높으므로 var은 배열로 선언됩니다.The array modifier has higher priority than the pointer modifier, so var is declared to be an array. 포인터 한정자는 배열 요소의 형식에 적용되므로 배열 요소는 int 값에 대한 포인터입니다.The pointer modifier applies to the type of the array elements; therefore, the array elements are pointers to int values.

int (*var)[5]; /* Pointer to array of int values */  

var에 대한 이 선언에서 괄호는 배열 한정자보다 포인터 한정자에 보다 높은 우선 순위를 부여하고, varint 값이 5개인 배열에 대한 포인터로 선언됩니다.In this declaration for var, parentheses give the pointer modifier higher priority than the array modifier, and var is declared to be a pointer to an array of five int values.

long *var( long, long ); /* Function returning pointer to long */  

함수 한정자도 포인터 한정자보다 우선 순위가 높기 때문에 var에 대한 이 선언은 varlong 값에 대한 포인터를 반환하는 함수로 선언합니다.Function modifiers also have higher priority than pointer modifiers, so this declaration for var declares var to be a function returning a pointer to a long value. 함수는 두 개의 long 값을 인수로 사용하도록 선언됩니다.The function is declared to take two long values as arguments.

long (*var)( long, long ); /* Pointer to function returning long */  

이 예제는 앞의 예제와 유사합니다.This example is similar to the previous one. 괄호는 포인터 한정자에 함수 한정자보다 높은 우선 순위를 부여하고, varlong 값을 반환하는 함수에 대한 포인터로 선언됩니다.Parentheses give the pointer modifier higher priority than the function modifier, and var is declared to be a pointer to a function that returns a long value. 여기에서도 함수는 두 가지 long 인수를 사용합니다.Again, the function takes two long arguments.

struct both       /* Array of pointers to functions */  
{                 /*   returning structures         */  
    int a;  
    char b;  
} ( *var[5] )( struct both, struct both );  

배열의 요소가 함수일 수는 없지만 이 선언은 함수에 대한 포인터 배열을 선언하는 방법을 대신 보여 줍니다.The elements of an array cannot be functions, but this declaration demonstrates how to declare an array of pointers to functions instead. 이 예제에서 var은 두 멤버가 포함된 구조체를 반환하는 함수에 대한 포인터 5개의 배열로 선언됩니다.In this example, var is declared to be an array of five pointers to functions that return structures with two members. 함수에 대한 인수는 동일한 구조체 형식 both를 사용하는 두 구조체로 선언됩니다.The arguments to the functions are declared to be two structures with the same structure type, both. *var[5] 주위에는 괄호가 필요합니다.Note that the parentheses surrounding *var[5] are required. 괄호 없이 아래와 같이 함수 배열을 선언하는 것은 잘못된 시도입니다.Without them, the declaration is an illegal attempt to declare an array of functions, as shown below:

/* ILLEGAL */  
struct both *var[5](struct both, struct both);  

다음 문은 포인터의 배열을 선언합니다.The following statement declares an array of pointers.

unsigned int *(* const *name[5][10] ) ( void );  

name 배열에는 다차원 배열로 구성된 50개의 요소가 있습니다.The name array has 50 elements organized in a multidimensional array. 요소는 상수인 포인터에 대한 포인터입니다.The elements are pointers to a pointer that is a constant. 이 상수 포인터는 매개 변수가 없고 부호 없는 형식에 대한 포인터를 반환하는 함수를 가리킵니다.This constant pointer points to a function that has no parameters and returns a pointer to an unsigned type.

다음 예제는 double 값이 세 개인 배열에 대한 포인터를 반환하는 함수입니다.This next example is a function returning a pointer to an array of three double values.

double ( *var( double (*)[3] ) )[3];  

이 선언에서 배열을 반환하는 함수가 잘못되었으므로 함수는 배열에 대한 포인터를 반환합니다.In this declaration, a function returns a pointer to an array, since functions returning arrays are illegal. 여기서 vardouble 값이 세 개인 배열에 대한 포인터를 반환하는 함수로 선언됩니다.Here var is declared to be a function returning a pointer to an array of three double values. var 함수는 인수를 하나 사용합니다.The function var takes one argument. 인수는 반환 값과 마찬가지로 double 값이 세 개인 배열에 대한 포인터입니다.The argument, like the return value, is a pointer to an array of three double values. 인수 형식은 복합 추상 선언자에서 제공됩니다.The argument type is given by a complex abstract-declarator. 인수 형식에서 별표 주위에 괄호가 필요합니다. 괄호가 없으면 인수 형식이 double 값에 대한 세 포인터의 배열이 됩니다.The parentheses around the asterisk in the argument type are required; without them, the argument type would be an array of three pointers to double values. 추상 선언자에 대한 설명과 예제는 추상 선언자를 참조하세요.For a discussion and examples of abstract declarators, see Abstract Declarators.

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

위의 예제와 같이 포인터는 다른 포인터를 가리킬 수 있으며 배열에는 배열이 요소로 포함될 수 있습니다.As the above example shows, a pointer can point to another pointer, and an array can contain arrays as elements. 여기서 var은 요소가 5개인 배열입니다.Here var is an array of five elements. 각 요소는 멤버가 두 개인 공용 구조체에 대한 포인터에 대한 포인터의 배열(요소가 5개임)입니다.Each element is a five-element array of pointers to pointers to unions with two members.

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

이 예제에서는 괄호의 위치에 따라 선언의 의미가 어떻게 바뀌는지를 보여 줍니다.This example shows how the placement of parentheses changes the meaning of the declaration. 이 예제에서 var은 공용 구조체에 대한 포인터의 배열(요소가 5개임)에 대한 포인터의 배열(요소가 5개임)입니다.In this example, var is a five-element array of pointers to five-element arrays of pointers to unions. typedef를 사용하여 복합 선언을 방지하는 방법에 대한 예제를 보려면 Typedef 선언을 참조하세요.For examples of how to use typedef to avoid complex declarations, see Typedef Declarations.

참고 항목See Also

선언 및 형식Declarations and Types