typedef 선언: 기존에 존재하는 자료형의 이름에 새 이름을 부여하는 것을 목적으로 하는 선언
typedef 선언에 있어서 새로운 이름의 부여는 가장 마지막에 등장하는 단어를 중심으로 이뤄진다.
typedef namel name2 name3;
가장 마지막에 등장한 name3가 namel name2’에 부여된 새로운 이름이 된다.
typedef로 정의되는 자료형의 이름은 대문자로 시작하는 것이 관례이다.
구조체의 정의와 typedef의 선언을 한데 묶는 것이 일반적이다.
typedef struct point
{
int xpos;
int ypos;
} Point;
위와 같이 구조체 point를 정의하면 구조체의 이름 point는 별 의미를 갖지 않게 된다. 따라서 구조체의 이름을 생략하는 것도 가능하다.
typedef struct
{
int xpos;
int ypos;
} Point;
함수의 인자로 구조체 변수가 전달될 수 있으며, 이러한 인자를 전달받을 수 있도록 구조체 변수가 매개변수의 선언으로 올 수 있다. 그리고 전달되는 구조체 변수의 값은 매개변수에 통째로 복사가 된다. 이는 구조체의 멤버로 배열이 선언되어도 동일하다.
구조체 변수를 대상으로는 매우 제한된 형태의 연산만 허용된다.
대입연산, & 연산, sizeof 연산 등.
#include <stdio.h>
typedef struct point
{
int xpos;
int ypos;
} Point;
int main(void)
{
Point pos1 = {1, 2};
Point pos2;
pos2 = pos1; // posl의 멤버 대 pos2의 멤버간 복사가 진행됨
printf("크기: %d \n", sizeof(pos1)); // pos1의 전체 크기 반환
printf("[%d, %d] \n", pos1.xpos, pos1.ypos);
printf("크기: %d \n", sizeof(pos2)); // pos2의 전체 크기 반환
printf("[%d, %d] \n", pos2.xpos, pos2.ypos);
return 0;
}
구조체 변수 간 대입연산의 결과로 멤버 대 멤버의 복사가 이루어진다.
함수를 정의해야 한다.
Q. 다음 구조체의 두 변수를 대상으로 저장된 값을 서로 바꿔주는 함수를 정의하고 이를 호출하는 예제를 작성해보자.
typedef struct point
{
int xpos;
int ypos;
} Point;
예를 들어서 다음과 같이 두 개의 구조체 변수가 선언된 상태에서,
Point pos1 = {2, 4};
Point pos2 = {5, 7};
이 두 구조체 변수를 대상으로, 혹은 두 구조체 변수의 주소 값을 대상으로 SwapPoint라는 이름의 함수를 호출하면 pos1 의 xpos, ypos에는 각각 5와 7이, 그리고 pos2의 xpos, ypos에는 각각 2와 4가 저장되어야 한다.
A.
#include <stdio.h>
typedef struct point
{
int xpos;
int ypos;
} Point;
SwapPoint(Point* p1, Point* p2)
{
int temp;
temp = (*p1).xpos;
(*p1).xpos = (*p2).xpos;
(*p2).xpos = temp;
temp = (*p1).ypos;
(*p1).ypos = (*p2).ypos;
(*p2).ypos = temp;
}
int main(void)
{
Point pos1 = { 2,4 };
Point pos2 = { 5,7 };
SwapPoint(&pos1, &pos2);
printf("(%d, %d) \n", pos1.xpos, pos1.ypos);
printf("(%d, %d) \n", pos2.xpos, pos2.ypos);
return 0;
}
구조체를 통해서 연관 있는 데이터를 하나로 묶을 수 있는 자료형을 정의하면, 데이터의 표현 및 관리가 용이해지고, 그만큼 합리적인 코드를 작성할 수 있게 된다.
구조체 변수도 구조체의 멤버로 선언될 수 있다.
#include <stdio.h>
typedef struct point
{
int xpos;
int ypos;
} Point;
typedef struct circle
{
Point cen;
double rad;
} Circle;
void ShowCircleInfo(Circle* cptr)
{
printf("[%d, %d] \n", (cptr->cen).xpos, (cptr->cen).ypos);
printf("radius: %g \n\n", cptr->rad);
}
int main(void)
{
Circle c1={{1, 2}, 3.5};
//구조체 변수가 멤버로 존재할 경우, 이렇듯 중괄호를 이용해서 구조체 멤버의 초기화를 구분지을 수 있다.
Circle c2={2, 4, 3.9};
//중괄호를 이용해서 구조체 변수의 초기화를 구분 짓지 않으면, 순서대로 초기화된다.
ShowCircleInfo(&c1);
ShowCircleInfo(&c2);
return 0;
}
구조체 변수를 초기화하는 경우에도 배열의 초기화와 마찬가지로 초기화하지 않은 일부 멤버에
대해서는 0으로 초기화가 진행된다.
Q. 좌 상단의 x, y 좌표가 [0, 0], 우 하단의 x, y 좌표가 [100, 100]인 좌표평면상의 직사각형 정보를 표현하기 위한 구조체 Rectangle을 정의하되, 다음 구조체를 기반으로 정의해보자.
typedef struct point
{
int xpos;
int ypos;
} Point;
그리고 Rectangle 구조체 변수를 인자로 전달받아서 해당 직사각형의 넓이를 계산해서 출력하는 함수와 직사각형을 이루는 네 점의 좌표정보를 출력하는 함수를 각각 정의해보자. 단, 좌표평면상에서 직사각형을 표현하기 위해서 필요한 점의 갯수는 4개가 아닌 2개이니, 직사각형을 의미하는
Rectangle 변수 내에는 두 점의 정보만 존재해야 한다.