구조체로 데이터의 묶음 만들기

여러 데이터를 하나로 묶는 구조체(Structure)를 공부해 볼게요. 이 구조체를 공부함으로써, 본격적으로 C에서 C++로의 확장을 준비하게 되는 것이랍니다.



강의들은 모두 무료입니다. 단, 저작권은 키클 코딩랩 에 있으며, 무단 복제 및 배포를 엄금합니다.
이를 어길 시, 본 사이트의 서버가 미국에 있으므로, 미국법에 의해 처벌될 수도 있습니다.




인적사항 관리 프로그램 코딩하기

원하는 폴더/디렉토리를 만들고 gedit 문서 편집기를 이용하여 "lec14_strt.c"라는 이름의 C 파일을 만들어 볼게요. 그리고, 아래처럼 표준입출력 라이브러리의 헤더파일(stdio.h)을 포함시키고, main 함수의 골격을 만들어 보세요. 이번 강의에서는, 아래 줄3에서 보듯이 전달인자가 없는 main 함수를 코딩해 볼게요.

lec14_strt.c
#include <stdio.h>

int main () {

}

이제 아주 간단한 인적사항 관리 프로그램을 코딩해 볼게요. 이 프로그램의 기능은 아주 간단해요. "흥부(Heungbu)"와 "놀부(Nolbu)"의 이름과 나이를 적절한 데이터타입의 변수에 저장하고, 이 인적사항들을 출력하는 것이지요. 이 프로그램을 아래 줄4~줄10처럼 코딩해 볼게요.

lec14_strt.c
#include <stdio.h>

int main ( ) {
	char *name0 = "Heungbu";
	int age0 = 47;
	char *name1 = "Nolbu";
	int age1 = 54;

	printf("Person0: %s, %d\n", name0, age0);
	printf("Person1: %s, %d\n", name1, age1);
}

줄4에서는, 흥부의 이름을 문자열 "Heungbu"로서 문자형 포인터 변수 name0에 저장하고 있어요.
줄5에서는, 흥부의 나이를 47세로 가정하여 정수형 변수 age0에 저장하고 있지요.
줄6에서는, 놀부의 이름을 문자열 "Nolbu"로서 문자형 포인터 변수 name1에 저장하고 있어요.
줄7에서는, 놀부의 나이를 54세로 가정하여 정수형 변수 age1에 저장하고 있답니다.
그리고, 줄9에서 흥부의 이름과 나이를 출력하고, 줄10에서 놀부의 이름과 나이를 출력하고 있지요.

이제, 파일을 저장하고 gedit 편집기 닫기를 하세요.
그리고, 아래처럼 컴파일 후 실행해 보면, 흥부와 놀부의 인적사항이 출력되는 것을 볼 수 있지요.

.../my_folder$ gcc lec14_strt.c
.../my_folder$ ./a.out
Person0: Heungbu, 47
Person1: Nolbu, 54
.../my_folder$




구조체로 인적사항 코딩하기

이 시점에서 위에서 만든 인적사항 관리 프로그램의 코드를 되새겨 볼 필요가 있어요.
바로, 줄4~줄7이 그 대상인데요. 흥부한테는 "name0"과 "age0", 놀부한테는 "name1"과 "age1"이라는 변수명을 사용했지요? 위에서는 흥부와 놀부 두 명만 관리 대상이어서 별 문제가 없었지만, 만약, 십만(100,000)명의 인적사항을 관리해야 한다면 어떻게 될까요? 위에서 사용한 작명 방식이라면, 마지막 사람의 이름과 나이는 "name99999"와 "age99999"이라는 변수명을 사용해야 되겠지요. 만약, 인적사항에 주소까지 추가하면, 모든 사람의 주소를 저장하기 위해 "address0" 부터 "address99999" 까지의 변수들도 사용해야 될 겁니다.
이렇게 코딩을 하면, 데이터들이 체계적이지 않고 코드의 가독성도 현저히 떨어질 거예요. 이것은 인적사항을 구성하는 데이터들이 구조화되지 않고 개별적으로 코딩이 됨으로써 발생하는 문제이지요.

만약, "Person"이라는 별도의 데이터타입이 있고, 그 데이터타입 안에 이름과 나이를 저장할 수 있는 변수들이 "char *name"과 "int age"처럼 선언될 수 있다면 어떨까요? Person이라는 데이터타입의 변수만 "Person person0" 이나 "Person person1234"처럼 구분해서 선언해 주고, 각 Person 데이터타입에 속하는 이름과 나이는 "name"과 "age"라는 변수명을 모두에게 사용할 수 있겠지요. (이 부분이 이해가 잘 되지 않는다면 조금만 기다려 주세요. 곧 모두 알게 될 거예요.)

C 에서는 위에서 상상해본 "Person"이라는 데이터타입처럼, 여러가지 데이터타입의 변수들을 품고 있는 별도의 데이터타입을 사용자가 원하는대로 만들수가 있답니다. 이것은 바로 구조체(Structure)라는 것을 통해 가능해진답니다. 그럼, 구조체에 대하여 알아볼까요?

[문법] 구조체 (Structure)

구조체를 이용하여 여러 속성들을 품는 새로운 데이터타입을 정의할 수 있다는 것, 잘 이해 했지요? 그럼, 앞서 코딩한 인적사항 관리 프로그램을 구조체를 이용하여 다시 코딩해 볼게요.
먼저, 문자형 포인터 변수 name과 정수형 변수 age를 속성으로 갖는 Person 구조체를 아래 줄3~줄6처럼 추가해 보지요. 이름 속성을 위해 선언한 변수 name의 데이터타입이 왜 문자형 포인터(char *)인지 기억이 나지 않는다면, 강의 main 함수 해부하기 - 문자와 문자열에서 꼭 확인하세요.

lec14_strt.c
#include <stdio.h>

struct Person {
	char *name;
	int age;
};

int main () {
	/*
	char *name0 = "Heungbu";
	int age0 = 47;
	char *name1 = "Nolbu";
	int age1 = 54;

	printf("Person0: %s, %d\n", name0, age0);
	printf("Person1: %s, %d\n", name1, age1);
	*/

	struct Person prs0;
	struct Person prs1;

	prs0.name = "Heungbu";
	prs0.age = 47;	
	prs1.name = "Nolbu";
	prs1.age = 54;

	printf("Person0: %s, %d\n", prs0.name, prs0.age);
	printf("Person1: %s, %d\n", prs1.name, prs1.age);
}

줄10~줄16은 앞에서 코딩했던 것인데요, 주석(Comment) 처리를 해서 효력이 없는 코드로 만들었답니다. 줄9에 "/*"를, 줄17에 "*/"를 추가했는데요, 어떤 코드가 "/*"와 "*/" 사이에 있으면 컴파일되지도 않고 실행되지도 않는답니다.
줄19~줄20은 Person 구조체 타입의 변수 prs0와 prs1을 선언하고 있어요. 흥부와 놀부 2명의 인적사항을 관리하는 것이니 두 개의 Person 타입의 변수가 필요한 것이죠.
줄19~줄20처럼, Person 구조체 데이터타입의 변수 prs0와 prs1를 선언하면, 각 구조체 변수는 name과 age 속성을 각각 따로 가지게 된답니다.
그래서, 줄22~줄23에서는, 접근 연산자 "."를 이용하여 Person 구조체 변수 prs0의 name과 age 속성에 흥부의 영문이름과 나이를 저장하고 있어요.
줄24~줄25에서는, prs1의 name과 age 속성에 놀부의 영문이름과 나이를 저장하고 있지요.
줄27~줄28에서는, 역시 "."를 이용하여 각각 prs0와 prs1의 name과 age 속성들을 출력하고 있답니다.

구조체를 이용하여 코딩해 보니 어떤가요? 각 사람의 이름과 나이 속성을 구분하기 위해 name0, name1, age0, age1과 같이 직관적이지도 체계적이지도 않는 코딩을 할 필요가 없지요? 물론, 사람을 구분하기 위해 prs0와 prs1라고 코딩을 하였지만, 각 사람은 분명 다르고 구분해줘야하니 이치에 맞다고 할 수 있지요.





컴파일 후 실행하기

이제, 파일을 저장하고 gedit 편집기 닫기를 하세요.
그리고, 아래처럼 컴파일 후 실행해 보면, 흥부와 놀부의 인적사항이 앞에서 했던 것과 같이 출력되는 것을 볼 수 있지요. 즉, 구조체를 이용한 코딩이 성공적으로 이루어졌다고 할 수 있는 것이지요.

.../my_folder$ gcc lec14_strt.c
.../my_folder$ ./a.out
Person0: Heungbu, 47
Person1: Nolbu, 54
.../my_folder$

강의에서 작성된 소스 코드 (source code)를 다운받으려면, 다음 링크를 클릭하세요: lec14_strt.c

혹시, 이해가 잘 안되는 부분에 대한 질문이 있거나 다루어 줬으면 하는 주제가 있으면, 화면 오른쪽 하단에 "질문하기" 버튼을 이용해 주세요.






발자취

2019-09-11 "키클 코딩랩 - 미국 공학박사 아빠의 코딩 연구소"로 이름 변경
2019-06-28 코딩 교실 공개
2019-03-18 코딩 교실 제작 시작

바로가기
Python 배움터
C/C++ 배움터
About
Contact
Privacy Policy
강의목록
질문하기
처음으로