C 구조체

프로그래밍/C 2019.05.21 댓글 Plorence

구조체(structure)

구조체는 하나 이상의 변수(포인터 변수와 배열 포함)를 묶어서 새로운 자료형을 정의하는 도구입니다.

구조체를 기반으로 우리는 새로운 자료형을 정의할 수 있습니다.

 

만약 프로그램상에서 마우스의 좌표 정보를 저장하고 관리해야 한다고 가정하면

다음과 같이 두 개의 변수를 선언해야 합니다.

int xpos; //마우스 x 좌표
int ypos; //마우스 y 좌표

그런데 이 둘은 항상 함께하기 마련입니다.
이 둘은 서로 독립된 정보를 표현하는것이 아니라, 마우스의 위치라는 하나의 정보를 표현하기 때문입니다.

struct point
{
    int xpos;
    int ypos;
}

point 라는 이름의 구조체를 정의한 결과

이때 point 라는 이름이 int나 double과 같은 자료형의 이름이 되는 것입니다.

기본 자료형을 묶어서 새로운 자료형을 만든 것입니다.

이를 가리켜 '사용자 정의 자료형'(user defined data type)'이라고 합니다.

 

구조체 변수의 선언과 접근

구조체 변수의 선언 방법은 struct type_name val_name;입니다.

예시로 

struct point pos;

접근 방법은 구조체 변수의 이름.구조체 멤버의 이름

으로 접근합니다.

만약 구조체 변수의 멤버 xpos에 20을 저장하려면 

pos.xpos = 20;

위와 같은 방법으로 대입합니다.

구조체 변수를 선언과 동시에 초기화도 가능합니다.

#include <stdio.h>
struct point {
    int xpos;
    int ypos;
};
int main(void) {
    struct point pos1 = {10,20};
    printf("%d %d \n", pos1.xpos, pos1.ypos);
}

이때 10,20은 각각 xpos, ypos에 저장됩니다.

 

구조체를 정의하는 이유

구조체를 통해서 연관 있는 데이터를 하나로 묶을 수 있는 자료형을 정의하면, 데이터의 표현 및 관리가 용이해지고, 그만큼 합리적인 코드를 작성할 수 있게 됩니다.

#include <stdio.h>
int main(void) {
       int xpos;
       int ypos;
}

위 코드는 이름을 통해 서로 연관되어 있다는 걸 알 수 있지만, 만약 그렇지 않은 경우 구조체를 이용해서 데이터를 묶어 서로 연관이 있다는 것을 알 수 있습니다.

struct Point
{
       int xpos;
       int ypos;
};

서로 연관되어 쓰인다면 첫 번째 예시보다 직관적입니다.

 

중첩된 구조체의 정의와 변수의 선언

구조체 변수도 구조체의 멤버로 선언될 수 있습니다.

구조체 안에 구조체 변수가 멤버로 존재하는 경우를 가리켜 '구조체의 중첩'이라고 합니다.

이런 방식은 링크드 리스트의 노드(구조체)에서 쓰입니다.

 

구조체 배열

#include <stdio.h>
struct point {
    int xpos;
    int ypos;
};
int main(void) {
    struct point pos1[4]; { //구조체 배열도 가능함!
        {123, 123}; //pos1[0]
        {456, 456}; //pos1[1]
        {789, 789}; //pos1[2]
        {012, 012}; //pos1[3]
    }
    printf("%d %d \n", pos1[0].xpos, pos1[0].ypos);
}

구조체를 가지고 배열로 만들 수 있습니다.

초기화도 동일한 방법으로 이루어집니다.

 

구조체 변수와 포인터

#include <stdio.h>
struct point
{
    int xpos;
    int ypos;
    struct person * ptr; //포인터 변수를 구조체 멤버로 선언이 가능하다.
};
struct person
{
    int aa;
};
int main(void) {
    struct point point1 = { 10,20 };
    struct point * ptr = &point1; //구조체 point도 포인터 변수를 통해 접근이 가능하다.
    (*ptr).xpos = 20;
    ptr->xpos = 30; //->을 사용해도 접근하는건 똑같다.(권장)
    printf("%d", point1.xpos);
    
}

포인터 변수를 구조체의 멤버로 선언이 가능합니다.

접근할 때 (*ptr).으로 접근하는 것도 가능하지만 포인터에서는 ->연산자로 접근해야 합니다.

이때  구조체 변수의 메모리 주소 값은 첫번째 멤버의 주소 값과 동일합니다.

즉 포인터 변수 ptr의 주소값은 xpos의 주소값과 일치합니다.

 

댓글