Namespaces
Variants

Member access operators

From cppreference.net

멤버 접근 연산자는 피연산자의 멤버에 접근할 수 있도록 합니다.

연산자 연산자 이름 예시 설명
[ ] 배열 첨자 a [ b ] 배열 a b 번째 요소에 접근
* 포인터 역참조 * a 포인터 a 를 역참조하여 해당 객체나 함수에 접근
& 주소 연산자 & a 객체나 함수 a 를 참조하는 포인터 생성
. 멤버 접근 a. b 구조체 또는 공용체 a 의 멤버 b 에 접근
- > 포인터를 통한 멤버 접근 a - > b a 가 가리키는 구조체 또는 공용체 의 멤버 b 에 접근

목차

첨자

배열 첨자 표현식의 형식은 다음과 같습니다

pointer-expression [ integer-expression ] (1)
integer-expression [ pointer-expression ] (2)

여기서

pointer-expression - 완전 객체에 대한 포인터 타입의 표현식
integer-expression - 정수 타입의 표현식

첨자 연산자 표현식은 lvalue 표현식 으로서, 그 타입은 pointer-expression 이 가리키는 객체의 타입입니다.

정의에 따르면, 첨자 연산자 E1 [ E2 ] 는 정확히 * ( ( E1 ) + ( E2 ) ) 와 동일합니다. 만약 pointer-expression 이 배열 표현식인 경우, 이는 lvalue-to-rvalue conversion 을 거쳐 배열의 첫 번째 요소를 가리키는 포인터로 변환됩니다.

포인터와 정수 간의 덧셈 정의 에 따라, 그 결과는 integer-expression 의 결과와 동일한 인덱스를 가진 배열 요소입니다 (또는, pointer-expression 이 어떤 배열의 i번째 요소를 가리키고 있었다면, 결과의 인덱스는 i에 integer-expression 의 결과를 더한 값입니다)

참고: 다차원 배열에 대한 자세한 내용은 array 를 참조하십시오.

#include <stdio.h>
int main(void)
{
    int a[3] = {1,2,3};
    printf("%d %d\n", a[2],  // n == 3
                      2[a]); // same, n == 3
    a[2] = 7; // subscripts are lvalues
    int n[2][3] = {{1,2,3},{4,5,6}};
    int (*p)[3] = &n[1]; // elements of n are arrays
    printf("%d %d %d\n", (*p)[0], p[0][1], p[0][2]); // access n[1][] via p
    int x = n[1][2]; // applying [] again to the array n[1]
    printf("%d\n", x);
    printf("%c %c\n", "abc"[2], 2["abc"]); // string literals are arrays too
}

출력:

3 3
4 5 6
6
c c

역참조

dereference 또는 indirection 표현식은 다음과 같은 형태를 가집니다

* 포인터-표현식

여기서

pointer-expression - 모든 포인터 타입의 expression

만약 pointer-expression 이 함수에 대한 포인터라면, 역참조 연산자의 결과는 해당 함수에 대한 함수 지정자입니다.

만약 pointer-expression 가 객체에 대한 포인터인 경우, 결과는 가리키는 객체를 지정하는 lvalue expression 입니다.

널 포인터, 수명이 끝난 객체를 가리키는 포인터(댕글링 포인터), 잘못 정렬된 포인터, 또는 불확정 값을 가진 포인터를 역참조하는 것은 정의되지 않은 행위입니다. 단, 역참조 연산자의 결과에 주소 연산자를 적용하여 무효화하는 경우(예: & * E )는 예외입니다.

#include <stdio.h>
int main(void)
{
    int n = 1;
    int* p = &n;
    printf("*p = %d\n", *p); // *p의 값은 n에 저장된 값입니다
    *p = 7; // *p는 lvalue입니다
    printf("*p = %d\n", *p);
}

출력:

*p = 1
*p = 7

주소 연산자

주소 연산자 표현식의 형식은 다음과 같습니다

& function (1)
& lvalue-expression (2)
& * expression (3)
& expression [ expression ] (4)
**참고사항:** - HTML 태그와 속성은 번역하지 않음 - ` `, `
`, `` 태그 내부 텍스트는 번역하지 않음
- C++ 관련 용어는 번역하지 않음
- 전문성과 정확성을 유지
1) 함수의 주소
2) 객체의 주소
3) 특별한 경우: & * 는 서로 상쇄되며, 둘 중 어느 것도 평가되지 않음
4) 특수한 경우: & [] 에 내포된 * 는 서로 상쇄되며, [] 에 내포된 덧셈만 평가됩니다.

여기서

lvalue-expression - lvalue 이며 bit-field 가 아니고 register 저장 클래스를 가지지 않는 모든 타입의 표현식

주소 연산자는 피연산자의 비-좌측값 주소를 생성하며, 피연산자 타입의 포인터를 초기화하는 데 적합합니다. 피연산자가 함수 지정자 (1) 인 경우, 결과는 함수에 대한 포인터입니다. 피연산자가 객체 (2) 인 경우, 결과는 객체에 대한 포인터입니다.

피연산자가 역참조 연산자인 경우, 아무런 동작도 수행되지 않습니다 (따라서 &*를 널 포인터에 적용해도 괜찮습니다). 단, 결과는 lvalue가 아닙니다.

피연산자가 배열 인덱스 표현식인 경우, 배열-포인터 변환과 덧셈 외에는 아무런 동작이 수행되지 않으므로, 크기가 N인 배열에 대해 &a[N]은 유효합니다 (끝을 지난 위치의 포인터를 얻는 것은 가능하지만, 역참조는 불가능합니다. 그러나 이 표현식에서는 역참조가 상쇄됩니다).

int f(char c) { return c;}
int main(void)
{
   int n = 1;
   int *p = &n; // 객체 n의 주소
   int (*fp)(char) = &f; // 함수 f의 주소
   int a[3] = {1,2,3};
   int *beg=a, *end=&a[3]; // end = a+3과 동일
}

멤버 접근

멤버 접근 표현식의 형식은 다음과 같습니다

expression . member-name

여기서

expression - struct 또는 union 타입의 표현식
member-name - expression 으로 지정된 struct 또는 union의 멤버를 지정하는 식별자

멤버 접근 표현식은 왼쪽 피연산자가 지정하는 struct 또는 union 의 명명된 멤버를 지정합니다. 이 표현식은 왼쪽 피연산자와 동일한 value category 를 가집니다.

왼쪽 피연산자가 const 또는 volatile 한정자를 가지면 결과도 동일하게 한정됩니다. 왼쪽 피연산자가 atomic 인 경우, 동작은 정의되지 않습니다.

참고: 구조체 또는 공용체 타입의 객체를 명명하는 식별자 외에도, 다음 표현식들이 구조체 또는 공용체 타입을 가질 수 있습니다: assignment , function call , comma operator , conditional operator , 그리고 compound literal .

#include <stdio.h>
struct s {int x;};
struct s f(void) { return (struct s){1}; }
int main(void)
{
    struct s s;
    s.x = 1; // 정상: s의 멤버를 변경함
    int n = f().x; // f()는 struct s 타입의 표현식
//  f().x = 1; // 오류: 이 멤버 접근 표현식은 lvalue가 아님
    const struct s sc;
//  sc.x = 3;  // 오류: sc.x는 const이며 할당할 수 없음
    union { int x; double d; } u = {1};
    u.d = 0.1; // union의 활성 멤버를 변경함
}

포인터를 통한 멤버 접근

멤버 접근 표현식의 형식은 다음과 같습니다

표현식 -> 멤버-이름

여기서

expression - pointer 타입의 표현식으로 struct 또는 union 을 가리킴
member-name - identifier 로, expression 이 가리키는 struct 또는 union의 멤버 이름

멤버 접근 포인터 표현식은 왼쪽 피연산자가 가리키는 struct 또는 union 타입의 명명된 멤버를 지정합니다. 이것의 값 범주는 항상 lvalue 입니다.

왼쪽 피연산자가 가리키는 유형이 const 또는 volatile 로 한정된 경우, 결과도 동일하게 한정됩니다. 왼쪽 피연산자가 가리키는 유형이 atomic 인 경우, 동작은 정의되지 않습니다.

#include <stdio.h>
struct s {int x;};
int main(void)
{
    struct s s={1}, *p = &s;
    p->x = 7; // 포인터를 통해 s.x의 값을 변경
    printf("%d\n", p->x); // 7을 출력
}

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
DR 076 C89 불필요한 간접 참조를 & 로 취소할 수 없음 취소 가능하도록 변경됨

참조문헌

  • C17 표준 (ISO/IEC 9899:2018):
  • 6.5.2.1 배열 첨자 (p: 57-58)
  • 6.5.2.3 구조체 및 공용체 멤버 (p: 58-59)
  • 6.5.3.2 주소 및 간접 연산자 (p: 59-61)
  • C11 표준 (ISO/IEC 9899:2011):
  • 6.5.2.1 배열 첨자 (p: 80)
  • 6.5.2.3 구조체 및 공용체 멤버 (p: 82-84)
  • 6.5.3.2 주소 및 간접 연산자 (p: 88-89)
  • C99 표준 (ISO/IEC 9899:1999):
  • 6.5.2.1 배열 첨자 연산 (p: 70)
  • 6.5.2.3 구조체 및 공용체 멤버 (p: 72-74)
  • 6.5.3.2 주소 및 간접 참조 연산자 (p: 78-79)
  • C89/C90 표준 (ISO/IEC 9899:1990):
  • 3.3.2.1 배열 첨자
  • 3.3.2.3 구조체 및 공용체 멤버
  • 3.3.3.2 주소 및 간접 연산자

참고 항목

일반 연산자
대입 증가
감소
산술 논리 비교 멤버
접근
기타

a = b
a + = b
a - = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b

++ a
-- a
a ++
a --

+ a
- a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

! a
a && b
a || b

a == b
a ! = b
a < b
a > b
a <= b
a >= b

a [ b ]
* a
& a
a - > b
a. b

a ( ... )
a, b
( type ) a
a ? b : c
sizeof


_Alignof
(C11부터)
(C23 이전)

alignof
(C23부터)

C++ documentation for Member access operators