Home C언어 (15) 구조체와 공용체
Post
Cancel

C언어 (15) 구조체와 공용체

C언어 (15) 구조체와 공용체

새로운 자료 구조인 구조체와 공용체, 열거형까지 알아보자.

구조체

image

배열이 타입이 같은 데이터를 하나로 묶는다면 구조체는 타입이 다른 데이터도 묶을 수 있다.
학생의 정보를 저장한다고 할 때 이름, 나이, 점수를 하나로 묶어 저장할 수 있으면 편할 것이다.
이런 여러개의 변수를 그룹화하여 새로운 자료형으로 만드는 것이 구조체이다.

구조체의 정의

우선 구조체를 만들려면 struct (구조체 이름)형태로 만든다.
그 다음 중괄호 안에는 구조체의 멤버 변수가 들어가고 마지막에는 ;(세미 콜론)가 필요하다.

1
2
3
4
struct point {
	int x;
	int y;
};

이렇게 정수형 x, y 좌표를 가진 구조체를 만들 수 있다.

구조체의 정의는 자료형을 새로 만드는 것과 같다고 생각하면 이해하기 편하다.
자료형을 만들었으면 그 자료형으로 변수를 선언해줘야 할 것이다.

구조체 변수의 선언과 사용

우선 구조체 변수를 선언하는 방법은 2가지가 있다.

1
2
3
4
5
#include <stdio.h>
struct point {
	int x;
	int y;
} p1, p2;

이렇게 구조체를 정의하면서 구조체 변수 p1, p2를 선언할 수도 있고,

1
2
3
4
5
6
7
8
9
#include <stdio.h>
struct point {
	int x;
	int y;
};
int main() {
	struct point p1, p2;
	return 0;
}

이렇게 구조체를 정의하고 따로 선언을 해줄 수도 있다.
새롭게 만든 struct point라는 자료형으로 변수를 선언해주는 것이다.
이 구조체 안의 변수를 멤버 변수라고 부르는데, 구조체 변수로 멤버 변수에 접근해보자.

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
struct point {
	int x;
	int y;
};
int main() {
	struct point p1, p2;
	p1.x = 10;
	p1.y = 20;
	printf("p1의 x좌표 : %d y좌표 : %d", p1.x, p1.y);
	return 0;
}

.연산자를 이용해서 (구조체 변수).(멤버 변수)의 방법으로 각각에 접근할 수 있다.
나머지 사용은 변수를 사용하듯이 쓰면 된다.

구조체 변수의 초기화

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
struct fish {
	int weight;
	double price;
};
int main() {
	struct fish f1;
	scanf("%d", &f1.weight);
	f1.price = f1.weight * 84.5;
	printf("f1의 무게 : %d 가격 : %lf\n", f1.weight, f1.price);

	struct fish f2 = { 100, 9860.5 };
	printf("f2의 무게 : %d 가격 : %lf\n", f2.weight, f2.price);
	return 0;
}

f2를 초기화하는 것처럼 선언과 동시에 중괄호를 통해 값을 넣을 수 있다.
선언과 따로 중괄호에 초기화 하는 방법도 있다.

1
2
struct fish f2;
f2 = (struct fish){ 100, 9860.5 };

이렇게 형변환을 해주듯이 값 앞에 구조체를 앞에 써주면 값을 넣어줄 수 있다.

1
2
3
4
struct fish {
	int weight = 0; // 에러
	double price = 2.5; // 에러
};

구조체의 정의 안에서 멤버 변수를 초기화하는 것을 불가능하니 주의하자.

구조체의 복사

같은 구조체 타입을 가졌다면 변수를 복사할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
struct fish {
	int weight;
	double price;
};
int main() {
	struct fish f1 = { 100, 9860.5 };
	struct fish f2;
	f2 = f1;
	printf("f1의 무게 : %d 가격 : %lf\n", f1.weight, f1.price);

	printf("f2의 무게 : %d 가격 : %lf\n", f2.weight, f2.price);
	return 0;
}

이렇게 f2 = f1을 통해 f1의 값을 f2로 복사할 수 있다.
하지만 멤버 변수들의 자료형이 같더라도 구조체 이름이 다르면 복사할 수 없다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
struct fish {
	int weight;
	double price;
};
struct co {
	int a;
	double d;
};
int main() {
	struct fish f1 = { 100, 9860.5 };
	struct co c;
	c = f1; // 에러 발생
	printf("f1의 무게 : %d 가격 : %lf\n", f1.weight, f1.price);

	return 0;
}

멤버 변수의 자료형들은 같지만 c는 struct co 구조체, f1은 struct fish 구조체 변수이므로 값을 넣을 수 없다.

그러면 같은 구조체 변수 간에 더하기나 뺄셈 같은 연산이 가능할까?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
struct fish {
	int weight;
	double price;
};
int main() {
	struct fish f1 = { 100, 9860.5 };
	struct fish f2 = { 80, 8890.2 };
	f1 + f2; // 에러 발생
	f1 - f2; // 에러 발생
	printf("f1의 무게 : %d 가격 : %lf\n", f1.weight, f1.price);

	printf("f2의 무게 : %d 가격 : %lf\n", f2.weight, f2.price);
	return 0;
}

이는 불가능하다. 구조체 변수들은 사용자가 만든 자료형이기 때문에 이런 연산을 할 수 없다.

1
2
3
4
5
struct fish f1 = { 100, 9860.5 };
struct fish f2 = { 80, 8890.2 };
if(f1==f2){ // 에러 발생
	printf("같습니다.\n");
}

같이 구조체를 비교하는 것 역시 안된다.

중첩 구조체

중첩 구조체란 구조체 안의 멤버 변수로 구조체가 들어있는 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
struct score {
	int math;
	int eng;
};
struct student {
	int no;
	struct score s;
};
int main() {
	struct student st1;
	struct student st2 = { 2, {90, 95} };
	st1.s.math = 100;
	st1.s.eng = 97;
	st1.no = 1;
	printf("학번 : %d 수학 : %d 영어 : %d\n", st1.no, st1.s.math, st1.s.eng);
	printf("학번 : %d 수학 : %d 영어 : %d", st2.no, st2.s.math, st2.s.eng);
	return 0;
}

초기화 방법은 struct student st2 = { 2, {90, 95} }; 처럼 구조체안의 구조체를 초기화하려면
중괄호를 한번 더 해서 초기화해줘야 한다.
각각에 접근하는 방법도, student의 score에 접근하니 st1.s 후 score의 멤버 변수에 접근한다.
그렇기에 st1.s.math, st1.s.eng 처럼 각각의 변수에 접근할 수 있다.

typedef

typedef는 자료형에 새로운 이름을 지어주는 키워드다.
구조체 변수를 선언할 때 struct (구조체 이름)을 다 적는 것은 너무 길다.
그 때 typedef struct score SCORE라는 코드를 적으면 SCORE은 struct score과 같은 의미를 가진다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
typedef struct score {
	int math;
	int eng;
} SCORE;
struct student {
	int no;
	SCORE s;
};
int main() {
	typedef struct student STU;
	STU st1;
	STU st2 = { 2, {90, 95} };
	st1.s.math = 100;
	st1.s.eng = 97;
	st1.no = 1;
	printf("학번 : %d 수학 : %d 영어 : %d\n", st1.no, st1.s.math, st1.s.eng);
	printf("학번 : %d 수학 : %d 영어 : %d", st2.no, st2.s.math, st2.s.eng);
	return 0;
}

typedef도 사용 방법이 두 가지가 있는데 struct score에 한 것처럼 정의를 하며 typedfef를 같이 쓴 뒤
구조체 맨 뒤에 재정의할 이름을 적는다.
두 번째 방법은 정의한 후 typedef struct student STU; 처럼 이름을 바꿀 수 있다.
이제 구조체 변수를 선언할 때 struct ~ 가 아니라 재정의한 짧은 이름으로 선언할 수 있다.


구조체의 메모리, 변수, 포인터, 함수 관련한 사용법에 대해 더 알아보자.

This post is written by PRO.