1 / 34

C 언어 ( STS2008 -04)

C 언어 ( STS2008 -04). 12. Enumerated, Structure, and Union Types. The type definition (typedef). typedef typedef 는 data type 에 다른 이름을 붙일 수 있게 한다 . typedef 문은 다음과 같이 사용한다 . 예를 들면 , 다음과 같이 typedef 를 사용하여 unsigned char 타입에 UCHAR 라는 다른 이름을 붙일 수 있다 .

victor-key
Download Presentation

C 언어 ( STS2008 -04)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C 언어 (STS2008-04) 12. Enumerated, Structure, and Union Types

  2. The type definition (typedef) • typedef • typedef는 data type에 다른 이름을 붙일 수 있게 한다. • typedef문은 다음과 같이 사용한다. • 예를 들면, 다음과 같이 typedef를 사용하여 unsigned char 타입에 UCHAR라는 다른 이름을 붙일 수 있다. • 위와 같을 때 unsigned char type의 변수 c를 정의하는 방법은 아래와 같다. • unsigned char c; //혹은 • UCHAR c; typedef unsigned char UCHAR;

  3. Enumerated types • enum은 상수대신 상징적인 이름을 사용할 수 있도록 해준다. • enum은 다음과 같은 두 가지 방법으로 선언이 가능하다. • enumValue는 상수대신사용하는 상징적인 이름이다. 이는 내부적으로 initializer에 의해 결정된 상수로 취급된다. 만약 initializer가 존재하지 않는 다면 가장 첫 이름은 0으로, 이후는 이전 enumValue의 값에 1증가된 값이 된다. Format 1: enumerated variable Format 2: enumerated tag enum {enumValue1 [= initializer1], enumValue2 [=initializer2], …} variable_identifier; enum tag {enumValue1 [= initializer1], enumValue2 [=initializer2], …}; enum tag variable_identifier;

  4. Enumerated types • 다음은 enum타입 선언의 예이다. • enum으로 선언된 months 같은 경우 최초의 값인 jan만 1로 초기화 되었다. 이후의 값은 이전 이름에 1증가된 값이므로 feb는 2, mar는 3으로 초기화 된다. • TV의 경우 모든 이름에 초기화 값이 존재하므로 해당 초기화 값으로 초기화가 된다. enum type 선언

  5. Enumerated types • 위 프로그램을 실행시키면 다음과 같은 결과가 출력된다. • enum으로 선언된 TV는 할당된 값을 그대로 출력하였음을 볼 수 있다. • enum으로 선언된 months의 경우 jan부터 dec까지 할당된 값을 출력하도록 했으므로 dec에 12가 할당되었음을 알 수 있다. kbs1 : 9 kbs2 : 7 mbc : 11 sbs : 6 1 2 3 4 5 6 7 8 9 10 11 12

  6. Structure • 구조체(structure)는 여러 개의 변수를 쉽게 사용할 수 있도록 해주기 위해서 하나의 이름으로 집단화시킨 하나 이상의 변수의 집합체이다. • 예를 들어 학생(student)마다 학번(id), 이름(name), 학점(gradePoints) 정보를 유지해야 한다면, 이 정보들을 하나로 묶어서 하나의 학생 정보로 관리하면 편리하다. 이렇게 여러 데이터 타입 변수들을 묶어서 집단화 시킨 것을 구조체라고 한다. • 배열은 같은 타입의 변수들의 집합이고, 구조체는 여러 가지 타입의 변수가 포함될 수 있다. 또한 구조체는 배열이나 다른 구조체를 포함하여 C의 모든 데이터 형을 포함할 수 있다.

  7. Structure • 구조체 변수는다음과 같이 정의한다. • 앞장의 student구조체를 생성한다면 다음과 같이 정의 하면 된다. struct { type1 fieldName1; type2 fieldName2; …. typeNfieldNameN; } variable_identifier; struct { int id; char name[26]; float gradePoints; }student;

  8. Structure • 앞에서 만든 student라는 변수에 id, name, gradePoints를 저장하면 학생 정보를 하나의 변수에 묶어서 사용할 수 있다. • 하지만, 학생이 여러 명인 경우라면 student와 같은 변수가 여러 개 필요하다. 하지만 그 때마다 struct { } 문을 이용해서 변수를 만들어 준다면 너무나 복잡할 것이다. 그래서 C 에서는 구조체 자체를 하나의 data type으로 만들어 사용할 수 있도록 해준다. 다음과같이 tag를 이용하면 구조체를 하나의 data type으로 만들 수 있다. structtag{ type1 fieldName1; …. typeNfieldNameN; } ; struct tag variable_identifier1; struct tag variable_identifier2; structstudent{ int id; char name[26]; float gradePoints; }; struct student Park; struct student Kim;

  9. Structure • typedef를 이용하면, 이와 같은 구조체 데이터 타입 변수의 선언을 더 간단하게 할 수 있다. • 앞의 student 구조체를 typedef을 이용해서 선언하면 다음과 같이 바꿀 수 있다. typedefstruct { type1 fieldName1; …. typeNfieldNameN; } type_identifier; typedefstruct { int id; char name[26]; float gradePoints; } student; student Park; student Kim; structstudent{ int id; char name[26]; float gradePoints; }; struct student Park; struct student Kim;

  10. Structure • 지금까지 살펴 본 구조체 정의 및 구조체 변수 선언 방법은 다음과 같이 정리할 수 있다. • 구조체 변수를 바로 만들어 사용하는 방법 • 태그를 이용하여 구조체 data type을 정의하고, 그 후에 변수를 선언하여 사용하는 방법 • typedef문을 이용하여 구조체 data type을 정의하고, 그 후에 변수를 선언하여 사용하는 방법

  11. Structure • 다음은 구조체 변수의 선언 후 초기화 모습을 보여준다. • 변수 선언 시에는 배열에서처럼 다음과 같은 초기화가 가능하다.

  12. Accessing structures • 앞에서와 같은 값의 할당은 구조체 변수의 선언시에만 가능하다. • 이 후에는 다음과 같이 ‘.’ 연산자(member operator)를 이용해서 구조체의 field(또는 member)에 접근할 수 있다. • 구조체의 각 멤버는 동일한 type의 일반적인 변수와 똑같은 방법으로 사용될 수 있다. • 예를 들어 좌측과 같은 구조체 birthday의 member인 month, day, year에 접근하기 위해서는 우측과 같이 연산자 ‘.’를 사용하면 된다. structdate_of_birth { int month; int day; int year; } birthday; birthday.month = 10; birthday.day = 16; birthday.year = 1980; printf(“%d-%d-%d\n”, birthday.year, birthday.month, birthday.day);

  13. Accessing structures • 구조체 변수간에 ‘=’연산자(대입 연산자)의 사용도 가능하다. • 동일한 구조체 type일 경우일 때만 사용 가능하다. • 구조체 변수간에 대입 연산자 사용시에는, 각 field의 값이 모두 대입된다. 구조체 정의 구조체 변수간에 assign

  14. Accessing structures • 위 프로그램을 실행한 결과는 다음과 같다. • 첫 출력 때는 구조체 변수 Kim과 Park이 생성될 때 초기화 된 값을 출력해주는 것을 알 수 있다. • 구조체 간에 대입 연산자를 사용한 이후 (Park = Kim;) 출력된 두 번째 결과에서는 구조체 변수 Park이 Kim이 가지고 있는 값과 동일한 값을 갖고 있음을 알 수 있다. Kim`s birthday : 1992-12-11 Park`s birthday : 1956-3-7 Park <- Kim Kim`s birthday : 1992-12-11 Park`s birthday : 1992-12-11

  15. Accessing structures • 구조체 변수에 대해서도 포인터 사용이 가능하다. • 구조체에 대한 포인터 선언 후 • 선언된 구조체 변수, sam1을 포인팅 하도록 연산 • 이후 *ptr은 sam1과 동일하게 사용될 수 있다.

  16. Accessing structures • 이후에 포인터를 통해 구조체의 멤버를 접근하기 위해서 다음과 같이 사용한다. • 포인터를 사용하지 않는다면 다음과 같이 접근할 수 있다. • sam1.x sam1.y sam1.t sam1.u • 구조체 멤버에 대한 포인터 연산자 사용시 다음을 주의 한다. • 멤버연산자(.) 의 우선순위가 참조연산자(*) 보다 높기 때문에 *ptr.x는 (*ptr).x와 다르다.

  17. Accessing structures ptr이 가리키는 구조체 변수의 member인 x • 다음 그림은 (*ptr).x 와 *ptr.x의 차이를 보여준다. 구조체변수 ptr의 member인 x가 가리키는 변수

  18. Accessing structures • selection operator ( -> ) • 앞에서 본 것처럼 구조체 포인터를 이용하여 구조체 멤버에 접근할 때는 괄호연산자를 사용해야 하는 불편함이 있다. • ex. (*ptr).x • selection operator(->)는 이런 경우에 사용할 수 있는 연산자이다. 예를 들면, 위의 구문은 다음과 같이 바꿀 수 있다. • ptr->x • selection operator는 구조체 포인터를 이용해서 멤버에 접근하고자 할 때 사용한다.

  19. Accessing structures • 앞에서 살펴본 예(p.29)를, -> 연산자를 사용하면 다음과 같이 표현할 수 있다.

  20. Accessing structures • 예제 프로그램 - 구조체 변수에 접근 <실행결과> dugbae(20091234) : 4.300000 Chulsoo(19990123) : 3.300000 구조체 정의 Dot notation을 이용해서 data 삽입 Selection notation을 이용해서 data 삽입 Indirection notation을 이용해서 data 출력

  21. Complex structures • C에서는 구조체의 멤버로써 다시 구조체를 사용하는 nested structure를 사용하는 것이 가능하다. • 병원에서 환자의 정보를 기록하는 프로그램을 작성한다면각 환자의 생년월일, 입원날짜, 퇴원날짜 같이 동일한 타입의 구조체를 여럿 사용할 필요가 있다. 이때는 다음과 같이 구조체를 분리해서 선언한 후 사용하는 것이 이후에 수정하기도 쉽고 이해하기도 편하다. • 아래 예제에서 DATE 구조체는 PATIENT 구조체 외에도 사용 가능하다.

  22. Complex structures • 아래와 같이 구조체 내부에서 멤버로써 구조체를 선언 하는 것도 가능하다. 즉 구조체 내부에서 새로운 구조체를 선언하는 것도, 구조체 밖에서 선언한 구조체를 멤버로 쓰는 것도 모두 가능하다. • 선언된 nested structure의 member는 notation을 반복하는 것으로 접근이 가능하다. 구조체 변수 start의 member인 year에 접근하기 위해서는 start.date.year와같이 반복해서 notation을 사용 구조체 변수 start의 member인 min에 접근하기 위해서는 start.time.min 와같이 반복해서 notation을 사용

  23. Complex structures • Nested structure 또한 structure처럼 초기화가 가능하다. • 위와 같은 구조체의 경우 아래와 같이 변수 start를 초기화 할 수 있다. STAMP start = {{2009, 1, 26}, {10, 30, 20}}; 2009 1 26 10 30 20 year month day hour min sec date time start

  24. Array of structure • 구조체 또한 type의 일종이므로 구조체 변수 또한 배열로 선언하고 사용 할 수 있다. • 예를 들어 앞에서 정의한 student 구조체를 가지고 살펴보자. 만약 관리해야 하는 학생의 수가 50명이라면 어떻게 할 것인가? structstudent{ int id; char name[26]; float gradePoints; }; struct student std1; struct student std2; … struct student std50; structstudent{ int id; char name[26]; float gradePoints; }; struct student std[50];

  25. Array of structure structstudent{ int id; char name[26]; float gradePoints; }; struct student std[50]; • 위와같이 정의된 구조체에 접근하는 방법은 아래와 같다. • 또한이전에 배운 포인터와 배열의 관계는 구조체의 배열에도 그대로 적용된다. std[0].id; //첫 번째 학생의 ID std[0].name; //첫 번째 학생의 이름 std[0].gradePoints; //첫 번째 학생의 성적 … std[49].id; //마지막 학생의 ID struct student *pstd; //포인터 변수를 선언 pstd = std; //포인터 변수는 배열의 시작을 가리킴 std[3].id = 20071234; //4번째 학생의 id가 20071234 printf(“%d\n”, (pstd+3)->id); //20071234가 출력된다.

  26. Structures and functions • 구조체 또한 구조체가 아닌 변수와 마찬가지로 함수의 인자로써 전달될 수 있다. • 기존의 변수가 함수의 인자로써 전달되는 방법 • 변수의 값이 함수의 인자로 전달되는 방법 (Call by value) • 변수의 주소를 함수의 인자로 전달하는 방법 (Call by reference) void CallByValue(int a) { … } void CallByReference(int *a) { … } main() { int a; CallByValue(a); CallByReference(&a); }

  27. Structures and functions • 구조체형식의 변수가 함수의 인자로써 전달되는 방법 • 구조체변수의 내용이 함수의 인자로 전달되는 방법 (Call by value) • 구조체 변수의 주소를 함수의 인자로 전달하는 방법 (Call by reference) • 멤버의 내용이 함수의 인자로 전달되는 방법 (Call by value) • 멤버의 주소를 함수의 인자로 전달하는 방법 (Call by reference) • 구조체변수를 인자로 전달하려면 호출하는 쪽(caller)이나 피호출자(callee) 모두 구조체 형식을 알아야 한다. typedefstruct { inti; … }str; void CallByValue2(str a) { … } void CallByReference2(str *a) { … } main() { str a; CallByValue(a.i); CallByReference(&a.i); CallByValue2(a); CallByReference2(&a); }

  28. Unions • 공용체(union)의 기본적인 구조와 사용법은 구조체(structure)와 동일하다. • 공용체 변수는 구조체 변수와 달리 struct라는 키워드 대신 union이라는 키워드를 쓴다. • 구조체 변수는 구성 멤버들에게 개별적인 메모리 공간을 할당한다. • 공용체 변수는 크기가 가장 큰 한 멤버에게만 메모리 공간만을 할당하고 이 공간을 공용체 내의 모든 멤버들이 공유해서 사용한다.

  29. Unions • 구조체와 공용체의 메모리 할당 Memory int struct { int I; short S; char C[2]; }s; 4 byte short 2 byte char[2] 2 byte Structure size : 8 byte Memory union { int I; short S; char C[2]; }u; int short char[2] 4 byte Union size : 4 byte

  30. Unions • nested structure와 비슷하게, 구조체가 공용체를 멤버로 갖는 것이 가능하고 공용체 또한 구조체를 멤버로 갖는 것이 가능하다. typedefstruct { char name[20]; char mail[20]; int mobile; }professor; typedefstruct { char name[20]; char major[10]; int ID; float cgpa; }student; typedefstruct { char type; union { professor prof; student stu; } u; }person; person type u prof name mail mobile stu name major ID cgpa

  31. Unions • 구조체 person은 학교에 등록된 사람을 저장하기 위한 데이터 타입으로써, 학생이나 교수를 저장할 수 있다. • person의 멤버인 u는 학생/교수의 정보를 저장하기 위한 공용체로써 교수정보에는 이름, 메일주소, 이동전화 번호를 저장하고 학생정보에는 이름, 전공, ID, CGPA를 저장한다. • u의 멤버 prof와 stu는 같은 메모리 공간을 공유해서 사용하므로 person이 가리키는 누군가는 학생이거나 교수여야 한다. • 구조체 person은 저장된 데이터가 교수의 것인지 학생의 것인지 구분하기 위해 char 타입의 변수 type을 둔다. 저장된 데이터가 교수의 것인 경우 ‘p’를, 학생의 것인 경우 ‘s’를 저장한다.

  32. Unions • 예제 프로그램 – nested structure, union 앞에서 살펴본 데이터 구조

  33. Unions • 예제 프로그램 – nested structure, union 데이터 초기화

  34. Unions • 예제 프로그램 – nested structure, union • 출력 결과 형식에 따라 출력 professor Kim kim@sogang.ac.kr, 1234567 (CS) 20091234 Chulsoo CGPA : 3.400000

More Related