Download presentation
Presentation is loading. Please wait.
Published by정화 사 Modified 8년 전
1
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 1 구 조 체 (1) 구조체 메커니즘은 다른 형의 변수들을 하나로 묶어 주는 방법을 제공한다. 간단한 예로 카드놀이를 위한 구조체를 정의해 보자. struct card { intpips; char suit; }; 이 선언에서 struct 는 키워드이고, card 는 구조체 태그 이름이다. 그리고 변수 pips 와 suit 는 구조체의 멤버이다.
2
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 2 struct card c1, c2; 이와 같은 선언은 파생된 자료형인 struct card 형을 생성한다. 선언은 틀로 생각할 수 있다. 즉, struct card 라는 형은 생성되지만 메모리는 할당되지 않는다. struct 키워드와 함께 태그 이름을 사용하여 이런 형의 변수를 선언할 수 있다. 구 조 체 (2)
3
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 3 struct card{ intpips; charsuit; } c1, c2; 이 선언은 두 식별자 c1 과 c2 를 위해 struct card 형의 기억공간을 할당한다 구조체 변수는 다음과 같이도 선언할 수 있다. 이 방법은 struct card 형의 정의와 c1 과 c2 의 선언을 동시에 한 것이다. 구 조 체 (3)
4
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 4 c1.pips = 3; c1.suit = 's'; 구조체의 멤버를 접근하기 위해서는 멤버 접근 연산자 “.” 을 사용한다. 다음과 같은 형태의 구조는 변수로 사용되며, 사용방법은 단순 변수나 배열 원소의 사용법과 같다. structure_variable. member_name 구 조 체 (4)
5
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 5 c2 = c1; 만일 c2 를 c1 과 같은 카드를 갖도록 하게 하려면 다음과 같이 쓰면 된다. 이것은 c2 의 각 멤버에 c1 의 대응 멤버의 값을 배정하도록 한다. 프로그래머는 구조체 형식을 사용할 때 보통 typedef 메커니즘을 사용한다. 다음은 예를 보인 것이다. typedefstruct cardcard; 이제 카드를 나타내는 변수가 필요할 경우 다음과 같이 기술한다. card c3, c4, c5; 구 조 체 (5)
6
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 6 구조체는 복잡해 질 수 있다. 즉, 배열이나 구조체를 멤버로 갖는 구조체가 있을 수 있으며, 구조체의 배열도 있을 수 있다. An example is struct card { int pips; char suit; } deck[52]; 여기서 식별자 deck 은 struct card 의 배열로 선언되었다. 구 조 체 (6)
7
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 7 태그 이름이 지정되지 않으면, 이 구조체형은 이후의 선언에서는 사용될 수 없다. An example is struct { int day, month, year; char day_name[4]; char month_name[4]; } yesterday, today, tomorrow; 태그 이름이 기술되지 않았으므로, 이런 형의 변수를 이후에는 선언할 수 없다. 구 조 체 (7)
8
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 8 struct date { int day, month, year; char day_name[4]; char month_name[4]; }; 이 예에서는 앞의 예제와는 다르게 구조체 태그 이름으로 date 를 갖지만, 이 형으로 변수는 선언되지 않았다. 따라서 이 선언은 틀로 생각할 수 있고, 이 형의 변수를 다음과 같이 선언할 수 있다. struct date yesterday, today, tomorrow; 구 조 체 (8)
9
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 9 구조체형을 명명하기 위해서 typedef 를 사용할 경우에는 태그 이름은 중요하지 않다. An example is typedef struct { float re; float im; } complex; complexa, b, c[100]; 프로그래머는 이러한 파생된 형을 명명하기 위해 typedef 를 사용하고 이것을 헤더파일에 저장함으로써 모듈성 및 이식성을 얻을 수 있다. 구 조 체 (9)
10
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 10 구조체 멤버 접근 (1) 100 명의 학생들이 있는 학급에 대한 정보를 생성하는 class_info 라는 프로그램을 작성한다고 가정하자. 이러한 프로그램을 작성할 경우 다음과 같은 헤더파일을 먼저 작성할 수 있다. In file class_info.h: #define CLASS_SIZE 100 struct student { char *last_name; int student_id; char grade; };
11
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 11 다른 파일에 다음과 같은 코드를 작성한다고 가정하자. #include "class_info.h" int main(void) { struct student tmp, class[CLASS_SIZE];..... }; 구조체 멤버 접근 (2)
12
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 12 이렇게 선언된 경우 변수 tmp 의 멤버에 다음과 같은 문장을 사용하여 값을 배정할 수 있다. tmp.grade = 'A'; tmp.last_name = "Casanova"; tmp.student_id = 910017; struct student { char *last_name; int studen_id; char grade; }; 구조체 멤버 접근 (3)
13
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 13 구조체 멤버는 포인터를 통해서도 접근될 수 있다. 이때 멤버 접근 연산자로 -> 를 사용한다. 포인터 변수가 구조체의 주소를 가지고 있는 경우, 그 구조체의 멤버는 다음과 같은 형식으로 접근될 수 있다. pointer_to_structure -> member_name 이 구조는 다음과 같은 형식으로도 쓸 수 있다. (*pointer_to_structure).member_name 이때 괄호가 꼭 필요하다. 구조체 멤버 접근 (4)
14
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 14 복소수를 더하는 함수를 작성하면서 -> 의 사용법을 살펴보자. In file complex.h: struct complex { double re;/* real part */ double im;/* imag part */ }; typedef struct complex complex; 구조체 멤버 접근 (5)
15
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 15 그리고, 다른 파일에 다음과 같은 코드를 작성했다고 가정하자. #include "complex.h" void add(complex *a, complex *b, complex *c) { a->re = b->re + c->re; a->im = b->im + c->im; } 구조체 멤버 접근 (6)
16
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 16 다음 표는 두 멤버 접근 연산자의 사용 방법들을 보여주고 있다. 이 표에서 사용자 정의형 struct student 는 이 절의 앞부분에 선언된 것이다. 구조체 멤버 접근 (7)
17
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 17 연산자의 우선순위와 결합법칙 : 최종 고찰
18
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 18 함수에서 구조체 사용 (1) typedef struct { charname[25]; intemployee_id; struct deptdepartment; struct home_address*a_ptr; doublesalary;..... } employee_data; C 에서 구조체는 함수의 인자로 사용되어 함수에 전달될 수도 있고, 함수로부터 리턴될 수도 있다. 다음과 같은 구조체를 가정해 보자.
19
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 19 employee_data update(employee_data e) {..... printf("Input the department number: "); scanf("%d", &n); e.department.dept_no = n;..... return e; } 이제 고용자 정보를 갱신하는 함수를 정의해 보자. 두 가지 방법으로 이 함수를 기술할 수 있는다. 첫번째 방법은 다음과 같다. 함수에서 구조체 사용 (2)
20
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 20 employee_datae; e = update(e); 위 함수를 호출하기 위해 다른 함수에서 다음과 같은 코드를 작성할 수 있다. 여기서 e 는 값으로 전달되므로, e 의 지역 복사본이 만들어진다. 그리고 구조체가 update() 로부터 리턴될 때, 이 값은 멤버 대 멤버 함수가 수행되어 e 에 배정된다. 함수에서 구조체 사용 (3)
21
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 21 void update(employee_data *p) {..... printf("Input the department number: "); scanf("%d", &n); p -> department.dept_no = n;..... } 구조체는 크기 때문에 컴파일러는 많은 복사 작업을 수행해야만 한다. 두 번째 방법으로 다음과 같이 기술 할 수도 있다. 함수에서 구조체 사용 (4)
22
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 22 employee_datae; e = update(&e); 위의 함수를 호출하기 위해서는 다른 함수에 다음과 같은 코드를 포함시켜야 한다. 여기서 e 의 주소가 전달되므로, update() 함수내에서 구조체의 지역복사는 필요하지 않다. 대부분의 응용 프로그램에서 두번째 방법이 첫 번째 방법보다 더 효율적이다. 함수에서 구조체 사용 (5)
23
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 23 구조체의 초기화 (1) 프로그래머에 의해 명시적으로 초기화되지 않은 구조체를 포함한 모든 외부 및 정적 변수는 시스템에 의해 자동적으로 0 으로 초기화 된다. 전통적인 C 에서는 단지 외부 및 정적 변수만이 초기화될 수 있었다. 그러나 ANSI C 는 구조체를 포함하여 자동변수도 초기화 된다.
24
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 24 card c = {13, 'h'}; /* the king of hearts */ complex a[3][3] = { {{1.0, -0.1}, {2.0, 0.2}, {3.0, 0.3}}, {{4.0, -0.4}, {5.0, 0.5}, {6.0, 0.6}}, }; /* a[2][] is assigned zeroes */ struct fruit frt = {"plum", 150}; struct home_address { char*street; char*city_and_state; longzip_code; } address = {"87 West Street", "Aspen, Colorado", 80526}; struct home_address previous_address = {0}; 함수에서 구조체 사용 (2)
25
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 25 공용체 (1) 공용체 (1) union int_or_float { inti; float f; }; 공용체도 구조체와 같은 파생형이다. 공용체는 구조체와 같은 구문 형식을 갖지만 각 멤버들은 같은 기억장소를 공유한다. 이 선언에서 union 은 키워드이고, int_or_float 는 공용체 태그 이름이며, 변수 I 와 f 는 공용체의 멤버이다.
26
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 26 union int_or_float a, b, c; 이 선언은 파생 자료형인 공용체 int_or_float 를 생성하게 된다. 이 선언은 형을 생성하지만 기억 장소는 할당되지 않으므로 틀로 생각할 수 있다. 이제 키워드 union 과 태그 이름을 사용하여 이 공용체 변수를 선언할 수 있다. 공용체 (2)
27
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 27 이 선언으로 식별자 a, b, c 에 대한 기억장소가 할당된다. 각 변수를 위해 컴파일러는 공용체의 멤버 중에서 가장 큰 기억장소를 요구하는 멤버의 요구만큼 기억장소를 할당한다. 공용체의 멤버 접근 방법은 구조체의 멤버 접근 방법과 동일하다. 공용체 (3)
28
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 28 typedef union int_or_float { inti; charf; } number; int main(void) { numbern; n.i = 4444; printf("i: %10d f: %16.10e\n", n.i, n.f); return 0; } 다음 예는 공용체에 저장된 내용을 여러 방법으로 해석하는 것을 보여주고 있다. 공용체 (4)
29
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 29 i: 4444 f: 0.6227370375e-41 i: 1166729216 f: 4.4440000000e+03 이 실험을 통해 시스템에서 int 형과 float 형이 어떻게 중첩되는지를 알 수 있다. 이 프로그램의 출력은 시스템 종속적이다. 다음은 현재 사용되는 시스템의 출력이다. 공용체 (5)
30
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 30 여기서 주의할 점은 시스템은 선택된 멤버 원소에 따라 저장된 값을 해석하게 된다는 것이다. 따라서 올바른 멤버를 선택하는 것은 프로그래머의 책임이다. 공용체는 주어진 기억장소에 대해 여러 가지 해석을 요구하는 응용 프로그램에서 유용하게 사용된다. 공용체 (6)
31
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 31 비트 필드 (1) 비트 필드 (1) 프로그래머는 구조체나 공용체에서 int 형이나 unsigned 형의 멤버를 사용할 경우, 그 멤버의 비트 수를 지정할 수 있다. 이러한 멤버를 비트 필드라 하고, 이와 연관된 비트 수를 폭이라 한다. 폭은 콜론 (:) 다음에 음수가 아닌 정수적형 상수 식으로 지정되며, 폭의 최대 크기는 기계 워드의 비트 수와 같다. 일반적으로 비트 필드는 구조체의 연속적인 멤버로 선언되며, 컴파일러는 이 멤버들을 최소의 기계워드의 수로 패킹한다.
32
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 32 struct pcard{ /* a packed representation */ unsigned pips : 4; unsigned suit : 2; }; 다음 예제를 보자. struct pcard 형의 변수는 0 부터 15 까지 16 개의 값을 저장할 수 있는 pips 라는 4 비트 필드와 각각 클럽, 다이아몬드, 하트, 스페이드를 나타내는 0,1,2,3 을 저장하는 suit 라는 2 비트 필드를 가진다. 비트 필드 (2)
33
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 33 struct pacrd c; 다음과 같은 선언을 가정해 보자. c 에 다이아몬드 9 를 배정하기 위해서는 다음과 같이 하면 된다. c.pips = 9; c.suit = 1; 구조체나 공용체내에서 비트 필드에 대한 구문 형식은 다음과 같다. bit_field_member ::= { int | unsigned } 1 { identifier } opt : expr expr ::= constant_integral_expression 비트 필드 (3)
34
University of Inchon 멀티미디어와 가상환경 연구실 (Marvelab) A Book on C Chap. 9 - 34 비트 필드를 사용하는 주된 이유는 메모리를 절약하는 데 있다. 4 바이트 워드를 갖는 기계에서 1 비트 변수를 저장할 경우 비트 필드를 사용하면 한 워드에 32 개의 변수를 저장할 수 있고, char 형 변수는 3 개를 저장할 수 있다. 따라서 비트 필드를 사용함으로써 많은 메모리를 절약할 수 있음을 쉽게 알 수 있다. 비트 필드 (4)
Similar presentations