간접 참조 및 주소 연산자

단항 간접 참조 연산자(*)는 포인터를 통해 값에 간접적으로 액세스합니다. 피연산자는 포인터 형식이어야 합니다. 연산 결과는 피연산자가 가리키는 주소에 있는 값입니다. 결과의 형식은 피연산자가 표시하는 형식과 동일합니다.

간접 참조 연산자의 결과는 피연산자가 형식에 대한 포인터 형식인 경우 형식입니다. 피연산자가 함수를 가리키는 경우 결과는 함수 지정자입니다. 개체를 가리키는 경우 결과는 개체를 지정하는 Ivalue입니다.

포인터 값이 유효하지 않으면 간접 참조 연산자의 결과가 정의되지 않습니다. 다음은 포인터 값을 유효하지 않게 만드는 가장 일반적인 조건 몇 가지입니다.

  • 포인터가 null 포인터입니다.

  • 포인터가 참조 시점에 수명이 이미 종료된 개체의 주소를 지정합니다. (예: 범위를 벗어나거나 할당이 취소된 개체)

  • 포인터가 가리키는 개체의 형식에 대해 부적절하게 정렬된 주소를 지정합니다.

  • 포인터가 실행 중인 프로그램에서 사용되지 않는 주소를 지정합니다.

단항 주소 연산자( & )는 해당 피연산자의 주소를 제공합니다. 피연산자는 다음 중 하나여야 합니다.

  • 선언된 register가 아니며 비트 필드가 아닌 개체를 지정하는 lvalue.

  • 단항 역참조(*) 또는 배열 역참조([]) 연산자의 결과.

  • 함수 지정자.

결과는 operand_type 형식 피연산자에 대한 operand_type 포인터 형식입니다.

피연산자가 단항 * 연산자의 결과이면, 연산자가 평가되지 않고 결과는 둘 다 생략된 것과 같습니다. 결과는 lvalue가 아니며 연산자에 대한 제약 조건이 여전히 적용됩니다. 피연산자가 [] 연산자의 결과인 경우, & 연산자와 [] 연산자가 포함하는 단항 *은 평가되지 않습니다. 결과는 & 연산자를 제거하고 [] 연산자를 + 연산자로 변경하는 것과 동일한 효과가 있습니다. 그렇지 않은 경우 결과는 피연산자가 지정한 개체 또는 함수에 대한 포인터입니다.

다음 예에서는 이러한 일반적인 선언을 사용합니다.

int *pa, x;
int a[20];

이 명령문은 주소 연산자( & )를 사용하여 a 배열의 여섯 번째 요소의 주소를 가져옵니다. 결과는 포인터 변수 pa에 저장됩니다.

pa = &a[5];

이 예제에서는 간접 참조 연산자(*)를 사용하여 pa에 저장된 주소의 int 값에 액세스합니다. 값이 정수 변수 x에 할당됩니다.

x = *pa;

이 예는 간접 참조 연산자를 x의 주소에 적용한 결과가 x와 동일하다는 것을 나타냅니다.

assert( x == *&x );

이 예는 함수에 대한 포인터를 선언하는 동일한 방법을 보여줍니다.

int roundup( void );     /* Function declaration */

int  *proundup  = roundup;
int  *pround  = &roundup;
assert( pround == proundup );

함수 roundup이 선언되면 roundup에 대한 두 개의 포인터가 선언되고 초기화됩니다. 첫 번째 포인터, proundup은 해당 함수의 이름만을 사용하여 초기화되지만 두 번째 포인터, pround는 초기화 시 주소 연산자를 사용합니다. 초기화는 동일합니다.

참조

간접 참조 연산자: *
주소 연산자: &