C 기본 문법 – 구조체와 공용체 – 1편: 구조체와 포인터 완전 정복
여러분 안녕하세요! 😊
오늘은 C 언어에서 구조체(structure)를 한 단계 더 깊게 사용하는 방법인 구조체와 포인터의 결합에 대해 배워볼게요.
🧠 구조체와 포인터를 같이 사용하면,
마치 지도와 내비게이션을 동시에 사용하는 것처럼,
원하는 데이터에 빠르고 유연하게 접근할 수 있게 돼요!
이 개념은 함수에 구조체를 전달하거나,
동적 메모리를 할당하거나,
구조체 배열을 효율적으로 관리할 때 꼭 필요한 지식이랍니다.
지금부터 예시와 함께 차근차근 알아볼까요? 😊
1. 구조체 복습
typedef struct {
char name[20];
int age;
float height;
} Person;
Person
구조체는 이름, 나이, 키를 저장할 수 있는 자료형이에요.
2. 구조체 포인터 선언
Person p1 = {"홍길동", 25, 173.5};
Person *ptr = &p1;
💡
*ptr
은p1
을 가리키는 포인터입니다!
3. 구조체 멤버 접근: 점(.) vs 화살표(->)
사용 방식 | 예시 | 설명 |
---|---|---|
점(.) 연산자 | p1.age |
일반 변수로 접근 |
화살표(->) 연산자 | ptr->age |
포인터로 접근할 때 사용 |
예시 코드
printf("이름: %s
", ptr->name);
printf("나이: %d
", ptr->age);
printf("키: %.1f
", ptr->height);
🎯
ptr->name
은(*ptr).name
과 같은 의미예요!
4. 구조체를 함수에 포인터로 전달하기
void printPerson(Person *p) {
printf("이름: %s, 나이: %d, 키: %.1f
", p->name, p->age, p->height);
}
int main() {
Person p = {"영희", 22, 167.8};
printPerson(&p); // 주소 전달
return 0;
}
💡 구조체를 포인터로 전달하면 복사 비용 없이 원본 접근이 가능합니다!
5. 구조체 포인터로 동적 메모리 할당
Person *p = (Person *)malloc(sizeof(Person));
strcpy(p->name, "철수");
p->age = 28;
p->height = 178.2;
printf("%s는 %d세이고, 키는 %.1fcm입니다.
", p->name, p->age, p->height);
free(p); // 꼭 메모리 해제!
🎯 메모리를 동적으로 관리할 때는 포인터를 사용하는 것이 필수랍니다.
6. 구조체 배열과 포인터
Person arr[3] = {
{"민수", 20, 175.3},
{"지연", 21, 162.5},
{"현우", 23, 180.1}
};
Person *p = arr; // 배열 이름은 포인터!
반복 출력
for (int i = 0; i < 3; i++) {
printf("%s - %d세 - %.1fcm
", (p+i)->name, (p+i)->age, (p+i)->height);
}
🔑 배열의 인덱스도
*(p+i)
또는(p+i)->
형태로 표현할 수 있어요!
7. 중첩 구조체와 포인터
typedef struct {
int year, month, day;
} Date;
typedef struct {
char name[20];
Date birth;
} Member;
Member m = {"가영", {1999, 7, 15}};
Member *mp = &m;
printf("생년월일: %d-%d-%d
", mp->birth.year, mp->birth.month, mp->birth.day);
🎯 구조체 안에 구조체가 있어도, 포인터 접근은 동일한 방식으로 가능합니다!
8. 구조체 포인터를 활용한 실용 예시
학생 정보 입력 함수
void inputStudent(Person *p) {
printf("이름 입력: ");
scanf("%s", p->name);
printf("나이 입력: ");
scanf("%d", &p->age);
printf("키 입력: ");
scanf("%f", &p->height);
}
메인 함수에서 사용
int main() {
Person s;
inputStudent(&s);
printf("학생 정보: %s, %d세, %.1fcm
", s.name, s.age, s.height);
return 0;
}
✅ 구조체 포인터 요약표
항목 | 설명 | 예시 |
---|---|---|
선언 | 구조체 포인터 선언 | Person *p; |
주소 저장 | 구조체 변수의 주소 | p = &s; |
멤버 접근 | -> 연산자 사용 |
p->age |
함수 전달 | 주소 전달로 원본 접근 | printPerson(&p); |
동적 할당 | malloc() 사용 | p = malloc(sizeof(Person)); |
⚠️ 구조체 포인터 사용 시 주의할 점
주의사항 | 설명 |
---|---|
포인터 초기화 필수 | 선언만 하고 접근하면 Segmentation Fault 발생 |
malloc 후 free 꼭 하기 | 메모리 누수 방지 |
-> 연산자와 . 연산자 혼동 주의 | 포인터일 땐 반드시 -> 사용 |
구조체 복사 시 깊은 복사 고려 | 포인터 멤버 있을 경우 얕은 복사 주의 |
마무리하며 💬
구조체와 포인터를 함께 사용하는 건,
C 언어의 유연성과 효율성을 극대화할 수 있는 강력한 도구입니다!
특히 실무나 대형 프로젝트에서는 구조체 포인터가 함수 간 데이터 전달,
구조적 설계, 동적 메모리 처리에 매우 중요하게 사용돼요.
🎯 구조체가 건물이라면, 포인터는 그 건물의 주소!
주소만 알아도 원하는 데이터에 자유롭게 접근할 수 있어요 🏠📍
다음 시간에는 구조체 배열과 동적 구조체 관리,
그리고 공용체(union) 개념까지 확장해서 알아볼게요.
더 궁금한 게 있다면 언제든지 질문해 주세요!
함께 성장하는 C 언어 마스터 여정, 화이팅입니다! 💪🚀