Quick Syntax
구조체 값에는 ., 구조체 포인터에는 ->를 씁니다. 함수가 원본 필드를 바꿔야 하면 Struct *를 받고 NULL 허용 여부를 계약합니다.
typedef struct {
char name[20];
int score;
} Student;
Student s = {"Kim", 90};
Student *ptr = &s;
ptr->score += 5;
s.score += 5; /* ptr->score와 같은 원본 필드 */값에는 ., 포인터에는 ->를 씁니다. 함수가 Student *를 받으면 호출자 원본을 수정할 수 있으므로 NULL을 허용하는지와 객체를 누가 해제하는지를 함께 정합니다.
문법
->는 구조체 포인터를 위한 전용 문법입니다. 의미상으로는 (*ptr).field와 같지만, 구조체 포인터를 자주 다루는 C에서는 이 축약형이 사실상 기본입니다.
Student s = {"Kim", 90};
Student *ptr = &s;
printf("%d\n", (*ptr).score);
printf("%d\n", ptr->score);수정 흐름
구조체를 값으로 넘기면 복사본을 수정하고, 구조체 포인터를 넘기면 원본을 직접 수정합니다. .와 ->의 차이보다 이 차이가 더 중요합니다.
void reset(Student *s) {
if (s != NULL) {
s->score = 0;
}
}동적 할당 구조체에서는 손에 들고 있는 값이 곧 포인터이므로 ->가 기본이 됩니다.
Student *s = malloc(sizeof(*s));
if (s != NULL) {
s->score = 100;
free(s);
}함수가 NULL을 허용하는지, NULL이면 실패를 반환하는지, 호출자가 free할 소유권을 받는지 prototype과 반환값으로 정합니다. 초기화되지 않은 필드가 남지 않게 Student *s = calloc(1, sizeof(*s));처럼 목적에 맞는 초기화도 선택합니다.
빠른 점검
- 값 변수 필드 접근이다:
. - 구조체 포인터 필드 접근이다:
-> - 원본 구조체를 수정한다: 포인터 전달
- 동적 할당 구조체다:
->+free - 포인터가 유효한지 먼저 확인
주의할 점
NULL 또는 해제된 구조체 포인터에 ->를 쓰면 즉시 위험한 동작으로 이어집니다.
Student *ptr = NULL;
/* ptr->score = 90; */구조체 포인터도 결국 포인터이므로, 유효 대상인지 먼저 확인하는 습관이 필요합니다.
참고 링크
2 sources