• 검색 결과가 없습니다.

컴퓨터프로그래밍 2014 2학기 - [이론] 10_ch15_여러 데이터를 하나로 묶는 구조체

N/A
N/A
Protected

Academic year: 2021

Share "컴퓨터프로그래밍 2014 2학기 - [이론] 10_ch15_여러 데이터를 하나로 묶는 구조체"

Copied!
51
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)
(2)

구조체가 필요한 경우 구조체 만들기 구조체와 데이터 구조체 변수, 구조체 멤버 간의 데이터 저장 구조체 배열 구조체 포인터 구조체 멤버가 배열 또는 포인터인 경우의 데이터 처리 구조체 형의 크기와 멤버의 위치 구조체와 함수 구조체를 헤더파일로 저장하여 사용하는 방법 구조체 속의 구조체(중첩된 구조체) 자기 참조 구조체

(3)

데이터는 "이은영"이라는 한 사람의 데이터이지만 여기에 서로 다른 여러 데이터 형이 포함되어 있다. 따라서 한 사람에 대한 여러 데이터를 변수로 처리한다고 하더라도 다른 사람의 데이터를 고려할 경우 많은 수의 변수가 필요할 것이고, 배열로 처리하더라도 서로 다른 데이터 형을 사용해야 할 것이다. 위와 같이 여러 항목에 대해 서로 다른 데이터 형을 포함하더라도 한 사람의 데이터로 묶어서 변수와 같이 다룰 수 있다면 편리할 것이다. 구조체(structure)라는 것을 이용하면 위와 같이 여러 항목의 데이터들을 하나의 이름으로 묶어서 사용할 수 있다. 다시 말해서 구조체는 서로 다른 데이터 형을 갖는 변수들을 대표 이름으로 묶어 놓는 것이라고 할 수 있다.

(4)

이 항목들은 전화번호를 새로 등록해야 하는 모든 사람에게 동일하게 적용되는 항목이며, 항목 중에는 문자로 입력하거나 숫자로 입력해야 하는 항목들이 섞여 있다. 만약 위와 같은 항목을 갖는 데이터를 저장한다고 할 때, 여러분은 어떤 방법을 사용하겠는가?

배열을 이용한다면?

(5)

만약 100명의 데이터를 저장해야 한다면 첨자를 하나 더 사용하여 2차원 배열에 저장해야 할 것이다. 그런데 배열은 동일한 데이터 형을 갖는 기억 공간이지만, 휴대전화의 항목들은 위에서와 같이 서로 다른 데이터 형을 갖는다. 배열을 이용하는 경우와 실제 휴대전화기에 연락처를 저장한 경우의 비교

(6)

구조체를 사용하기 위해서는 먼저 포함될 항목을 정하여 구조를 만들어야 하는데 이를 구조체 정의라 한다. 구조체를 정의한다는 것은 특별한 구조를 갖는 데이터 형을 만드는 것인데 이를 구조체 형이라 한다. 구조체 형을 만든다는 것은 붕어빵을 만들기 위한 틀을 만드는 것과 같다. 이 틀이 먼저 만들어져야 붕어빵을 만들 수 있다.

(7)

구조체 태그(tag) : 구조체를 대표하는 이름 구조체 멤버(member) : 구조체를 구성하는 항목 구조체 멤버는 일반 변수와 마찬가지로 데이터 형을 사용하여 변수를 정의하며, 포인터나 배열도 사용할 수 있다. 구조체 정의에 의해 새로운 데이터 형이 만들어지는 것이므로 구조체 태그가 곧 구조체 형이다. 구조체 형은 붕어빵 틀을 만드는 것이고 구조체 멤버는 붕어빵에 넣을 재료들의 이름에 비유할 수 있다.

(8)

문자열을 저장하는 방법으로 포인터를 사용하거나 문자형 배열을 이용할 수 있으므로 다음과 같이 두 가지 방법 중 하나를 사용할 수 있다.

왼쪽 구조체 형 user과 오른쪽 구조체 형 person은 멤버의 구성은 비슷하지만 구조체 형 user는 멤버인 name과 phone을 문자형 배열로 선언하였고,

오른쪽 구조체 형 person은 포인터를 사용하였다.

구조체를 정의할 때 주의해야 할 것은 마지막 부분 오른쪽 중괄호 } 다음에 ';' (semicolon)을 넣어야 한다.

(9)

데이터를 저장하기위해서 변수나 배열을 생각하듯이 구조체에 데이터를 저장하려면 변수나 배열이 필요하다.

앞에서 정의한 구조체 형 user는 int나 char와 같이 새로운 데이터 형으로 사용할 수 있다.

int 형 변수, int 형 배열 그리고 int 형 포인터를 선언하듯이 구조체 형을 이용하여 다음과 같이 user 형 구조체 변수, 구조체 배열 그리고 구조체 포인터를 선언하여 사용할 수 있다.

(10)

실행결과

구조체 변수를 초기화할 때 중요한 것은 구조체 멤버의 정의 순서대로 초기화 데이터를 작성해야 한다. 다음은 구조체 변수 d를 초기화 하는 방법이다. 구조체 형을 함수 main의 내부에 정의하면 오직 함수 main안에서만 사용할 수 있는 데이터 형으로 범위가 좁아지므로 다른 여러 함수들에서도 해당 구조체 형을 사용하기 위해서는 함수 main의 외부에서 정의하여 사용한다.

(11)

다음과 같이 선언한 구조체 person으로 한 사람의 데이터를 초기화하여 출력하시오.

(12)

[방법 1] 일반적인 방법.

[방법 2] 구조체를 정의하면서 동시에 구조체 변수를 선언하는 방법. [방법 3] typedef는 데이터 형의 이름을 새로운 이름으로 바꿀 때 사용.

(13)

문자형 포인터에는 문자열을 직접 대입할 수 있지만 문자형 배열에서는 배열 이름이 포인터 상수이므로 초기화를 제외하고는 문자열을 직접 배열에 대입할 수 없고, 함수 strcpy를 사용하거나 입력 함수 scanf를 이용하여 대입하는 방법을 사용한다.

실행결과

(14)

공백을 포함하는 문자열을 입력 받으려면 함수 gets를 사용한다. scanf 사용시 일반 변수에 대해서는 &를 붙이지만 포인터나 배열은 이름 자체가 메모리 상의 주소를 가리키므로 &를 사용하지 않는다.

실행결과

(15)

같은 구조체 형으로 선언된 변수에 대해서는 구조체 단위나 멤버 단위로 데이터를 주고받을 수 있지만 서로 다른 구조체 형으로 선언된 구조체 변수끼리는 구조체 단위로 데이터를 주고받을 수 없다. 그러나 서로 다른 구조체 형이라 하더라도 멤버의 데이터 형이 같다면 데이터를 서로 주고받을 수 있다. 변수에 대해 대입 연산자를 사용하여 다른 변수의 값을 저장하는 것과 동일한 방법으로 구조체 변수 간에 대입 연산자를 사용하면 멤버 간 1:1 대응을 통해 데이터를 전달한다.

(16)

구조체 변수 간에 대입 연산자를 사용하면 멤버 간 1:1 대응을 통해 데이터를 전달한다.

(17)

서로 다른 구조체 형 변수라 하더라도 멤버의 데이터 형이

같으면 서로 데이터를 주고받을 수 있다.

(18)
(19)

포인터 변수를 사용하듯 구조체 포인터도 사용이 가능하다. 포인터 변수는 데이터가 아닌 메모리 주소를 가리킨다. 따라서 구조체 포인터에는 데이터를 대입시키는 것이 아니라 구조체 변수의 주소를 대입하여 사용한다. 변수와 포인터 변수간의 처리에서 동일한 데이터 형으로 선언하여 사용하듯이 구조체 변수와 구조체 포인터 역시 동일한 구조체 형으로 선언하여 사용한다.

(20)

실행결과

구조체 변수나 구조체 배열에 대해 멤버의 데이터를 출력할 경우 도트 연산자 '.'을 사용하지만 구조체 포인터에 대해서는 간접 연산자 '->'을 사용한다. (pt+i)->name은 pt[i].name과 동일하다.

(21)

배열 이름은 포인터 상수 이므로 문자열을 직접 대입할 수 없으므로 문자열 복사 함수인 strcpy를 사용한다. 멤버가 포인터일 경우에는 데이터의 공간이 컴파일 이전에 확보되지 않기 때문에 실행 중에 데이터의 공간을 확보하기 위해 동적 할당을 사용한다.

(22)

멤버가 포인터일 경우에는 데이터의 공간이 컴파일 이전에 확보되지 않기 때문에 실행 중에 데이터의 공간을 확보하기 위해 동적 할당을 사용한다. 연산자 '.'가 '*'보다 연산의 우선순위가 높기 때문에 괄호를 사용한다.

(23)

모든 데이터 형에 크기(byte)가 있듯이 구조체 형도 멤버의 데이터 형에 따라 크기가 결정된다. 다음의 구조체 형 user에서 char name[20]은 20 byte, char phone[14]는 14 byte 그리고 int quick은 4 byte의 크기를 가지므로 구조체 형 전체의 크기는 38이 될 것으로 예상하나 실행결과는? 이유는?

실행결과와 이유

32 bit의 환경에서 대부분의 입출력에서 word 단위인 4 byte의 크기를 기준으로 합니다. 위의 구조체 형 정의에서 int 형 멤버 quick이 제외되었다면 user의 크기는 당연히 34(20+14)가 되지만 int 형인 멤버 quick 이 4 byte의 크기를 갖기 때문에 멤버에 대한 접근 역시 4 byte 단위로

맞춰주기 위해 padding 공간(2 byte)을 포함하여 38이 아니라 40의 크기를 갖는다.

(24)

실행결과

멤버에 대한 접근을 4 byte 단위로 맞춰주기 위해 멤버 name과 quick 사이에 2 byte 크기(②)의 padding 포함

(25)

변수나 포인터와 같이 구조체 형 데이터는 함수의 인자로 사용할 수 있으며, 함수의 결과값으로 구조체를 반환할 수도 있다. 구조체를 함수의 인자로 사용할 경우에는 구조체 변수, 구조체 배열 그리고 구조체 포인터를 사용할 수 있으며, 이때 함수 인자의 데이터 형을 구조체 형으로 선언하여 사용한다. 함수의 결과로 구조체를 반환하는 경우에는 함수의 데이터 형을 구조체 형 으로 정의하여 사용한다.

(26)

구조체를 함수의 인자로 사용할 경우에는 함수 인자의 데이터 형을 구조체 형으로 선언하여 사용한다.

(27)

함수 인자로 포인터를 사용할 때는 구조체 변수에 대해 주소 연산자를 사용하거나 포인터 변수를 사용할 수 있다.

(28)

함수의 인자로 구조체 배열을 사용할 때는 구조체 형 포인터로 선언한다.

(29)

함수의 결과값으로 구조체를 반환하려면 함수의 데이터 형을 구조체 형으로 정의해야 한다.

(30)

구조체는 일반적으로 헤더 파일(*.h)에 저장하여 사용한다. 비교적 간단한 프로그램이라면 앞에서와 같이 프로그램의 앞부분에 구조체를 정의하여 사용할 수 있지만 여러 개로 나누어진 프로그램에서 동일한 구조체를 사용할 경우, 구조체의 정의가 조금이라도 차이가 난다면 많은 문제가 발생할 수 있다. 따라서 구조체가 정의된 파일을 헤더 파일로 저장한 다음, #include에 의해 공통적으로 사용하는 것이 좋다.

(31)
(32)

구조체는 모든 데이터 형을 포함할 수 있기 때문에 구조체의 멤버로 또 다른 구조체를 사용할 수 있으며, 이를 구조체 안의 구조체 즉, 중첩된 구조체

(33)
(34)
(35)
(36)
(37)

자기 참조(self-referential) 구조체란 멤버의 데이터 형으로 자신의 구조체 형을 사용한다는 의미이다.

구조체 자체를 멤버로 사용할 수는 없지만 구조체의 데이터 형과 같은

포인터를 멤버로 가지는 것은 가능하다. 이렇게 함으로써 결국 포인터 멤버는 자기 자신을 가리키게 된다.

자기 참조 구조체는 자료 구조(data structure)에서 연결 리스트(linked list)나 트리(tree)를 구현하는데 있어서 필요한 구조체이다.

(38)
(39)
(40)

구조체(structure)란?

배열요소는 모두 동일한 데이터 형을 갖지만 구조체는 다음과 같이 서로 다른 데이터 형을 갖는 변수들을 대표 이름으로 묶어 놓는 것을 의미한다. 구조체는 사용자가 필요에 의해 정의하여 사용할 수 있는 사용자 정의의 데이터 형이다. 구조체 선언은 키워드 struct를 사용하며 다음의 구조체 형 student는 사용자가 정의하는 새로운 데이터 형으로 사용된다.

(41)

구조체를 정의한다는 것은?

구조체 태그(tag) : 구조체를 대표하는 이름 구조체 멤버(member) : 구조체를 구성하는 항목 구조체 멤버는 일반 변수와 마찬가지로 데이터 형을 사용하여 변수를 정의하며, 포인터나 배열도 사용할 수 있다. 구조체 정의에 의해 새로운 데이터 형이 만들어지는 것이므로 구조체 태그가 곧 구조체 형이다. 구조체 형은 붕어빵 틀을 만드는 것이고 구조체 멤버는 붕어빵에 넣을 재료들의 이름에 비유할 수 있다.

(42)

구조체와 데이터

데이터를 저장하기위해서 변수나 배열을 생각하듯이 구조체에 데이터를 저장하려면 변수나 배열이 필요하다.

int 형 변수, int 형 배열 그리고 int 형 포인터를 선언하듯이 구조체 형을 이용하여 다음과 같이 user 형 구조체 변수, 구조체 배열 그리고 구조체 포인터를 선언하여 사용할 수 있다.

(43)

구조체 변수의 초기화와 출력

구조체 변수를 초기화할 때 중요한 것은 구조체 멤버의 정의 순서대로 초기화 데이터를 작성해야 한다. 구조체 형을 함수 main의 내부에 정의하면 오직 함수 main안에서만 사용할 수 있는 데이터 형으로 범위가 좁아지므로 다른 여러 함수들에서도 해당 구조체 형을 사용하기 위해서는 함수 main의 외부에서 정의하여 사용한다.

(44)

구조체변수에 데이터를 대입하는 방법

문자형 포인터에는 문자열을 직접 대입할 수 있지만 문자형 배열에서는 배열 이름이 포인터 상수이므로 초기화를 제외하고는 문자열을 직접 배열에 대입할 수 없고, 함수 strcpy를 사용하거나 입력 함수 scanf를 이용하여 대입하는 방법을 사용한다.

(45)

구조체 변수간, 멤버간의 데이터 저장

같은 구조체 형으로 선언된 변수에 대해서는 구조체 단위나 멤버 단위로 데이터를 주고받을 수 있지만 서로 다른 구조체 형으로 선언된 구조체 변수끼리는 구조체 단위로 데이터를 주고받을 수 없다. 그러나 서로 다른 구조체 형이라 하더라도 멤버의 데이터 형이 같다면 데이터를 서로 주고받을 수 있다. 변수에 대해 대입 연산자를 사용하여 다른 변수의 값을 저장하는 것과 동일한 방법으로 구조체 변수 간에 대입 연산자를 사용하면 멤버 간 1:1 대응을 통해 데이터를 전달한다.

(46)
(47)

구조체 포인터

구조체 변수나 구조체 배열에 대해 멤버의 데이터를 출력할 경우 도트 연산자 '.'을 사용하지만 구조체 포인터에 대해서는 간접 연산자 '->'을 사용한다. (pt+i)->name은 pt[i].name과 동일하다.

(48)

구조체와 함수

변수나 포인터와 같이 구조체 형 데이터는 함수의 인자로 사용할 수 있으며, 함수의 결과값으로 구조체를 반환할 수도 있다. 구조체를 함수의 인자로 사용할 경우에는 구조체 변수, 구조체 배열 그리고 구조체 포인터를 사용할 수 있으며, 이때 함수 인자의 데이터 형을 구조체 형으로 선언하여 사용한다. 함수의 결과로 구조체를 반환하는 경우에는 함수의 데이터 형을 구조체 형 으로 정의하여 사용한다.

(49)
(50)
(51)

자기참조 구조체

자기 참조(self-referential) 구조체란 멤버의 데이터 형으로 자신의 구조체 형을 사용한다는 의미이다. 구조체 자체를 멤버로 사용할 수는 없지만 구조체의 데이터 형과 같은 포인터를 멤버로 가지는 것은 가능하다. 이렇게 함으로써 결국 포인터 멤버는 자기 자신을 가리키게 된다.

자기 참조 구조체는 자료 구조(data structure)에서 연결 리스트(linked list)나 트리(tree)를 구현하는데 있어서 필요한 구조체이다.

참조

관련 문서

- 방습층을 두면 수증기가 이동하지 못하므로, 수증기 이 동시 방습층 앞에서는 노점 온도가 높으나 방습층 뒤에 서는 노점온도가 급격히 낮아짐. -

높은 학생을 선발하여서 장학금을 수여한다. 가장 평점이 높은 학생을 찾아서 학생의 이름과 학번, 평점을 화면에 출력하는 프로그램을 작성하여 보자.. 복소수를

 person이라는 구조체를 만들어보자. 이 구조체에는 문자 배열로 된 이름, 사람의 나이를 나타내는 정수값, 각 개인 의 월급을 나타내는 float값 등이 변수로

CHAP 3:배열,

일반적인 디자인에는 Bard Button, MICKey, Copak, Entristar 가 있습니다.. 내시경을

 job_code가 0이면 job_info 공용체 변수의 school_name을 사용하고, job_code가 1이면 company_name을 사용한다...

 자기 참조 구조체(self-referential structure)는 특별한 구조체로서 구성 멤버 중에 같은 타입의 구조체를.. 가리키는

링크드리스트( Linked List ) 라고 한다. 매우 중요하지만,