본문 바로가기
정글 2기/자료구조(C언어)

[C언어] 구조체 포인터 사용하기

by Dean30 2021. 9. 4.
728x90

[C언어] 구조체 포인터 사용하기

다른 자료형과 마찬가지로 구조체도 포인터를 선언할 수 있으며,  malloc 함수를 이용하여 동적 메모리를 할당할 수 있다.

 

#define _CRT_SECURE_NO_WARNINGS    // strcpy 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h>    // strcpy 함수가 선언된 헤더 파일
#include <stdlib.h>    // malloc, free 함수가 선언된 헤더 파일

struct Person {    // 구조체 정의
    char name[20];        // 구조체 멤버 1
    int age;              // 구조체 멤버 2
    char address[100];    // 구조체 멤버 3
};

int main()
{
    struct Person *p1 = malloc(sizeof(struct Person));    // 구조체 포인터 선언, 메모리 할당

    // 화살표 연산자로 구조체 멤버에 접근하여 값 할당
    strcpy(p1->name, "낑깡");
    p1->age = 30;
    strcpy(p1->address, "서울시 성동구");

    // 화살표 연산자로 구조체 멤버에 접근하여 값 출력
    printf("이름: %s\n", p1->name);       // 낑깡
    printf("나이: %d\n", p1->age);        // 30
    printf("주소: %s\n", p1->address);    // 서울시 성동구

    free(p1);    // 동적 메모리 해제

    return 0;
}

 

'구조체 .으로 멤버에 접근'하고 '구조체 포인터는 ->로 멤버에 접근'한다. 구조체 포인터에서 .으로 멤버에 접근하려면 괄호와 역참조를 사용하면 된다.

 

p1->age; // 화살표 연산자로 멤버에 접근
(*p1).age; // 구조체 포인터를 역참조한 뒤 .으로 멤버에 접근

 

구조체의 멤버가 포인터일 때 역참조를 하려면 맨 앞에 *를 붙이면 된다. 이 때 구조체 변수 앞에 *가 붙어있어도 멤버의 역참조이지 구조체 변수의 역참조가 아니다.

  • *구조체변수.멤버
  • *구조체포인터->멤버

 

#include <stdio.h>
#include <stdlib.h>

struct Data {
    char c1;
    int *numPtr;    // 포인터
};

int main()
{
    int num1 = 10;
    struct Data d1;    // 구조체 변수
    struct Data *d2 = malloc(sizeof(struct Data));    // 구조체 포인터에 메모리 할당

    d1.numPtr = &num1;
    d2->numPtr = &num1;

    printf("%d\n", *d1.numPtr);     // 10: 구조체의 멤버를 역참조
    printf("%d\n", *d2->numPtr);    // 10: 구조체 포인터의 멤버를 역참조

    d2->c1 = 'a';
    printf("%c\n", (*d2).c1);      //  a: 구조체 포인터를 역참조하여 c1에 접근
                                   // d2->c1과 같음
    printf("%d\n", *(*d2).numPtr); // 10: 구조체 포인터를 역참조하여 numPtr에 접근한 뒤 다시 역참조
                                   // *d2->numPtr과 같음

    free(d2);

    return 0;
}

 

구조체 변수 d1의 멤버 numPtr을 역참조 하는 방법과 구조체 포인터 d2의 멤버 numPtr을 역참조 하는 방법

 

 

역참조한 것을 괄호로 묶으면 구조체 변수를 역참조한 뒤 멤버에 접근한다는 뜻이 된다.

*(*d2).numPtr처럼 구조체 포인터를 역참조하여 numPtr에 접근한 뒤 다시 역참조할 수도 있다.

  • (*구조체 포인터).멤버
  • *(*구조체 포인터).멤버
d2->c1 = 'a';
printf("%c\n", (*d2).c1);      //  a: 구조체 포인터를 역참조하여 c1에 접근
                               // d2->c1과 같음
printf("%d\n", *(*d2).numPtr); // 10: 구조체 포인터를 역참조하여 numPtr에 접근한 뒤 다시 역참조
                               // *d2->numPtr과 같음

 

여기서 (*d2).c1 은 d2->c1과 같다

*(*d2).numPtr 은 *d2->numPtr과 같다.

 

 

 

 

코딩도장 49 구조체 포인터 사용하기 참조

728x90

댓글