|

C 점 연산자 화살표 연산자 차이: struct 포인터를 읽는 기준

C 언어 점 연산자 화살표 연산자 struct 포인터 대표 이미지
점 연산자와 화살표 연산자의 차이는 값이 struct 자체인지, struct를 가리키는 포인터인지에서 시작됩니다.

점 연산자 화살표 연산자 차이는 C 언어에서 struct와 포인터를 함께 배우는 순간 자주 막히는 부분입니다. `student.name`은 자연스러운데 `p->name`과 `(*p).name`이 나오면 코드가 갑자기 낯설어집니다.

핵심은 왼쪽 값이 struct 자체이면 점, struct를 가리키는 포인터이면 화살표입니다. 이 글은 C 언어의 member access operator 규칙을 기준으로 예제와 실수 포인트를 정리합니다.

C 점 연산자와 화살표 연산자 차이 요약 카드
struct 변수는 점, struct 포인터는 화살표로 멤버에 접근합니다.

점 연산자 화살표 연산자를 가르는 기준

C 언어에서 struct 멤버에 접근하려면 왼쪽에 무엇이 있는지 먼저 봐야 합니다. 왼쪽이 struct 변수 자체이면 `.`을 쓰고, struct를 가리키는 포인터이면 `->`를 씁니다.

struct Student {
    int id;
    int score;
};

struct Student s = {1, 90};
struct Student *p = &s;

printf("%d\n", s.score);
printf("%d\n", p->score);

두 출력은 같은 값을 가리키지만 접근 과정은 다릅니다. `s`는 struct 값이고, `p`는 그 값을 가리키는 주소입니다.

struct 변수에는 점 연산자

점 연산자 `.`은 struct 또는 union 객체의 멤버에 접근합니다. 변수 자체가 이미 struct라면 포인터를 거칠 필요가 없습니다.

struct Point {
    int x;
    int y;
};

struct Point point = {10, 20};
point.x = 30;
printf("%d\n", point.x);

struct 포인터에는 화살표 연산자

포인터는 struct 자체가 아니라 struct가 있는 위치를 담습니다. 그래서 먼저 포인터가 가리키는 대상을 따라가야 멤버에 접근할 수 있습니다.

struct Point point = {10, 20};
struct Point *ptr = &point;

ptr->x = 30;
printf("%d\n", ptr->x);

`ptr->x`는 `ptr`이 가리키는 struct의 x 멤버라는 뜻입니다. 포인터를 많이 쓰는 C 코드에서 매우 자주 등장합니다.

p->field는 (*p).field와 같다

화살표 연산자는 완전히 새로운 동작이라기보다 포인터 역참조와 점 연산자를 합친 축약 문법입니다. `p->score`는 `(*p).score`와 같은 의미입니다.

printf("%d\n", (*p).score);
printf("%d\n", p->score);

괄호가 필요한 이유는 연산자 우선순위 때문입니다. `*p.score`라고 쓰면 `p.score`를 먼저 해석하려고 해서 의도와 달라집니다.

함수 인자로 struct 포인터를 받는 이유

struct 크기가 커지면 값을 통째로 복사하는 것보다 포인터를 넘기는 편이 자연스러울 수 있습니다. 또 함수 안에서 원본 struct를 수정해야 할 때도 포인터가 필요합니다.

void update_score(struct Student *student, int score) {
    student->score = score;
}

update_score(&s, 95);

이 예제에서 `student`는 포인터이므로 함수 안에서는 `student->score`로 멤버에 접근합니다.

자주 생기는 실수

  • struct 변수인데 `->`를 쓴다
  • struct 포인터인데 `.`을 쓴다
  • `(*p).field`에서 괄호를 빼먹는다
  • 포인터가 NULL일 수 있는데 바로 `p->field`로 접근한다

실무 체크리스트

  1. 왼쪽 값의 타입을 먼저 본다
  2. struct 값이면 `.`을 사용한다
  3. struct 포인터이면 `->`를 사용한다
  4. `->`는 `(*p).field`의 축약이라고 읽는다
  5. 포인터가 유효한지 확인해야 하는 상황인지 판단한다

정리

C 언어 점 연산자와 화살표 연산자 차이는 외울 문법이 아니라 왼쪽 값의 타입을 읽는 문제입니다. struct 자체는 점, struct 포인터는 화살표라고 잡으면 포인터 코드가 훨씬 덜 낯설어집니다.

C 포인터와 struct 흐름은 C 언어 포인터와 배열 차이, C언어 포인터 쉽게 이해하기, C 언어 struct와 typedef 차이와 함께 보면 좋습니다. 외부 기준은 cppreference – Member access operators, cppreference – Struct declaration, cppreference – Pointer를 확인했습니다.

함께보면 좋은 글