C 기본 문법 – 구조체와 공용체 – 1 – 구조체와 포인터

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;

💡 *ptrp1을 가리키는 포인터입니다!


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 언어 마스터 여정, 화이팅입니다! 💪🚀

답글 남기기