Chap.23 구조체와 사용자 정의 자료형 2

xyzw·2022년 9월 12일
0

C

목록 보기
6/6

23-1; 구조체의 정의와 typedef 선언

typedef 선언

typedef 선언: 기존에 존재하는 자료형의 이름에 새 이름을 부여하는 것을 목적으로 하는 선언
typedef 선언에 있어서 새로운 이름의 부여는 가장 마지막에 등장하는 단어를 중심으로 이뤄진다.

typedef namel name2 name3;

가장 마지막에 등장한 name3가 namel name2’에 부여된 새로운 이름이 된다.
typedef로 정의되는 자료형의 이름은 대문자로 시작하는 것이 관례이다.

구조체의 정의와 typedef 선언

구조체의 정의와 typedef의 선언을 한데 묶는 것이 일반적이다.

typedef struct point
{
	int xpos;
	int ypos;
} Point;

구조체의 이름 생략

위와 같이 구조체 point를 정의하면 구조체의 이름 point는 별 의미를 갖지 않게 된다. 따라서 구조체의 이름을 생략하는 것도 가능하다.

typedef struct
{
	int xpos;
    int ypos;
} Point;

23-2; 함수로의 구조체 변수 전달과 반환

함수의 인자로 전달되고 return문에 의해 반환되는 구조체 변수

함수의 인자로 구조체 변수가 전달될 수 있으며, 이러한 인자를 전달받을 수 있도록 구조체 변수가 매개변수의 선언으로 올 수 있다. 그리고 전달되는 구조체 변수의 값은 매개변수에 통째로 복사가 된다. 이는 구조체의 멤버로 배열이 선언되어도 동일하다.

구조체 변수를 대상으로 가능한 연산

구조체 변수를 대상으로는 매우 제한된 형태의 연산만 허용된다.
대입연산, & 연산, 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;
}

구조체 변수 간 대입연산의 결과로 멤버 대 멤버의 복사가 이루어진다.

구조체 변수를 대상으로 덧셈이나 뺄셈을 하려면?

함수를 정의해야 한다.

문제

1

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;
}

23-2; 구조체의 유용함에 대한 논의와 중첩 구조체

구조체를 정의하는 이유

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

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

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

#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으로 초기화가 진행된다.

문제

1

Q. 좌 상단의 x, y 좌표가 [0, 0], 우 하단의 x, y 좌표가 [100, 100]인 좌표평면상의 직사각형 정보를 표현하기 위한 구조체 Rectangle을 정의하되, 다음 구조체를 기반으로 정의해보자.

typedef struct point
{
	int xpos;
	int ypos;
} Point; 

그리고 Rectangle 구조체 변수를 인자로 전달받아서 해당 직사각형의 넓이를 계산해서 출력하는 함수와 직사각형을 이루는 네 점의 좌표정보를 출력하는 함수를 각각 정의해보자. 단, 좌표평면상에서 직사각형을 표현하기 위해서 필요한 점의 갯수는 4개가 아닌 2개이니, 직사각형을 의미하는
Rectangle 변수 내에는 두 점의 정보만 존재해야 한다.

0개의 댓글