2019-1 st 프로그래밍입문 (1) 10 장. 구조체 박종혁교수 서울과학기술대학교컴퓨터공학과 UCS Lab Tel: 970-6702 Email: jhpark1@seoultech.ac.kr
목차 구조체의기본 구조체의개념 구조체의정의 구조체변수의선언및초기화 구조체변수의사용 구조체변수간의초기화와대입 구조체변수의비교 typedef 구조체의활용 구조체배열 구조체포인터 함수의인자로구조체전달하기 비트필드 구조체의멤버로다른구조체변수사용하기 공용체와열거체 열거체 공용체 2
구조체의정의 서로다른데이터형의변수들을하나로묶어서사용하는기능 사용자정의형을만드는방법을제공 함께사용되는변수들을묶어서구조체를정의한다. struct contact 이새로운데이터형이된다. 3
구조체의필요성 int number; char name[10]; double grade; 4
구조체와배열 구조체 vs 배열 같은타입의집합 다른타입의집합 5
구조체의장점 통계자료나성적등과같이관련있는서로다른자료형을한덩어리 ( 집합 ) 로만들어처리 연관있는데이터를한덩어리로묶으면프로그램의관리와구현이용이 순서대로정렬 (sort) 하는경우구조체단위로처리되므로간단 네트워크프로그램을작성할때소켓이나헤더 (header) 의 format( 형식 ) 을구조체로묶어서처리 함수를반환할때한개의데이터가아닌구조체단위로묶어서전달할수있음 6
구조체정의문의위치 7
사용자정의형으로서의구조체 구조체를정의하면새로운데이터형이만들어짐 데이터형만정의할뿐구조체변수가생성되는것은아님 구조체의멤버는구조체변수를선언해야메모리에할당됨 sizeof 연산자로구조체의바이트크기를구할수있음 구조체의크기는멤버들의크기의합보다크거나같다. 구조체형은 struct 키워드와태그이름을함께사용해야함 태그명만사용하면안된다. 8
예제 : 구조체의정의 9
구조체변수의선언 (1/2) 구조체변수가메모리에할당될때구조체의멤버들이선언된순서대로메모리에할당됨 10
구조체변수의선언 (2/2) 구조체를정의하면서구조체변수를함께선언할수있음 구조체를정의하면서변수를함께선언할때는구조체의태그이름을생략할수있음 이름이없으므로나중에다시사용할수없다. struct app_info { char name[128]; char path[128]; int version; } this_app; struct { char name[128]; char path[128]; int version; } this_app; 구조체변수를함께선언한다. 11
구조체변수의초기화 (1/2) { } 안에멤버들의초기값을멤버가선언된순서대로나열 12
구조체변수의초기화 (2/2) 초기값이멤버의개수보다부족하면나머지멤버들은 0 으로초기화 멤버의개수보다초기값을더많이지정하면안됨 초기값으로 { 0 } 을지정하면모든멤버가 0 으로초기화 13
구조체변수의사용 구조체의멤버에접근하려면멤버접근연산자 (.) 를이용 구조체변수를여러개선언하면, 각각의구조체변수는서로다른메모리에할당됨 14
예제 : 구조체변수의선언및사용 15
멤버접근연산자 일반구조체멤버접근연산자 c1.pips = 3; c1.suit = 's'; c2.pips = c1.pips; c2.suit = c1.suit; 포인터를통한구조체멤버접근연산자 pointer_to_structure -> member_name 다른방법 (*pointer_to_structure).member_name 16
멤버접근연산자 - 예제 struct complex { double re; /* real part */ double im; /* imag part */ }; typedef struct complex complex; void add(complex *a, complex *b, complex *c) { a -> re = b -> re + c -> re; a -> im = b -> im + c -> im; } 17
멤버접근연산자 18
구조체변수간의초기화 구조체변수를다른구조체변수로초기화하면, 동일한멤버간에 1:1 로복사해서초기화함 19
구조체변수간의대입 같은구조체형의변수를대입할때도동일한멤버간에 1:1 로대입함 구조체변수를초기화할때처럼 { } 안에나열된값을대입할수는없음 구조체의멤버인배열끼리대입하는것은컴파일에러 20
예제 : 구조체변수간의초기화와대입 21
구조체변수의비교 구조체변수끼리직접관계연산자로비교해서는안됨 두구조체변수의값이같은지비교하려면구조체변수끼리비교하는대신멤버대멤버로비교해야함 22
예제 : 구조체변수의비교 같지않습니다.\n"); 23
typedef 기존의데이터형에대한별명 (alias) 24
typedef 의사용목적 : 이식성 이식성 : 하나의소스파일로여러플랫폼에서수정없이컴파일되고실행될수있는특성 25
typedef 의사용목적 : 가독성 1 바이트크기의 2 진데이터를저장하는변수선언 unsigned char 형을 byte 라는이름으로정의 2 진데이터값을저장하는용도로사용하는변수라는의미 26
구조체배열 (1/2) 같은구조체형의변수를여러개묶어서사용 27
구조체배열 (2/2) 구조체의멤버에접근하려면 arr[i].member 형식으로접근 28
예제 : 구조체배열 29
예제 : 구조체배열의검색 30
구조체포인터 구조체변수의주소를저장하는포인터 구조체포인터로구조체변수의멤버에접근하려면간접멤버접근연산자인 -> 연산자를사용 31
예제 : 구조체포인터 32
구조체포인터의활용 (1/2) CONTACT *recent = NULL; // 마지막으로검색한연락처를가리키는포인터 while (1) { printf( 이름 (. 입력시종료 )? ); scanf( %s, name); if (strcmp(name,. ) == 0) // name이. 이면 while 탈출 break; index = -1; // 이름을찾을수없으면 -1 for (i = 0; i < size; i++) {... } if (index >= 0) { // 검색성공 printf("%s의전화번호 : %s\n", arr[index].name, arr[index].phone); recent = &arr[index]; // recent는찾은원소를가리킨다. } else // 검색실패 printf(" 연락처를찾을수없습니다.\n"); } 33
구조체포인터의활용 (2/2) 34
예제 : 구조체포인터의활용 35
함수의인자로구조체전달하기 (1/3) 값에의한전달 구조체를복사해서전달 시간적 공간적성능저하 36
예제 : 구조체를값으로전달하는경우 37
함수의인자로구조체전달하기 (2/3) 포인터에의한전달 구조체를복사하지않고전달하려면포인터로전달 38
예제 : 구조체를포인터로전달하는경우 39
예제 : 구조체형의출력매개변수를가진함수의정의 40
함수의인자로구조체전달하기 (3/3) 구조체변수를함수의매개변수로전달하는방법 1. 함수의매개변수는구조체포인터형을선언 2. 구조체변수가입력매개변수일때는 const 키워드를지정 3. 구조체를매개변수로전달받는함수를호출할때는구조체변수의주소를인자로전달 4. 함수를정의할때는매개변수인포인터로구조체의멤버에접근 41
비트필드 (1/3) 구조체의멤버를비트단위로사용하도록설정할수있음 42
비트필드 (2/3) 비트필드멤버에주어진비트로표현할수있는범위를넘어서는값을저장하면오버플로우가발생 구조체안에일반멤버와비트필드를함께정의할수도있음 DATE dday; dday.year = 18; dday.month = 11; dday.day = 40; 오버플로우가발생해서 8 이된다. typedef struct date { unsigned short year : 7; unsigned short month : 4; unsigned short day : 5; char the_day_of_week[4]; } DATE; 일반멤버를함께정의할수있다. 43
예제 : 비트필드의정의및사용 44
비트필드 (3/3) 중간에일부비트를비워두고멤버를특정비트에할당할수있음 45
구조체의멤버로다른구조체변수사용하기 구조체변수안에다른구조체변수가멤버로포함될수있음 typedef struct point { int x, y; } POINT; typedef struct line { POINT start, end; } LINE; LINE ln1 = { {10, 20}, {30, 40} }; 입력매개변수이므로 const 포인터로전달 double get_length(const LINE *ln) { int dx = ln->end.x - ln->start.x; int dy = ln->end.y - ln->start.y; return sqrt(dx*dx + dy * dy); } 46
예제 : LINE 구조체의정의및사용 ( 47
열거체 정수형변수가특정값들중한가지값을가질때유용하게사용 정수형변수가가질수있는값들을열거상수로정의 48
열거체의정의 열거체는 C 컴파일러에의해 int 형으로처리됨 열거상수는정수형상수가됨 따로지정하지않으면열거상수는 0 부터 1 씩증가되는값으로정의됨 열거상수를특정값으로정의할수도있음 2 3 4 49
예제 : 열거체와열거상수의정의및사용 50
열거형과다른방법과의비교 정수사용기호상수열거형 switch(code) { case 1: printf( LCD TV\n ); break; case 2: printf( PDP TV\n ); break; } 컴퓨터는알기쉬우나사람은기억하기어렵다 #define LCD 1 #define PDP 2 switch(code) { case LCD: printf( LCD TV\n ); break; case PDP: printf( PDP TV\n ); break; } 기호상수를작성할때오류를저지를수있다 enum tvtype { LCD, PDP }; enum tvtype code; switch(code) { case LCD: printf( LCD TV\n ); break; case PDP: printf( PDP TV\n ); break; } 컴파일러가중복이일어나지않도록체크한다 51
공용체 (1/2) 공용체의멤버들은같은주소에할당되고, 서로메모리를공유함 52
공용체 (2/2) 공용체의크기는멤버중가장큰멤버의크기와같음 공용체의모든멤버는메모리를공유하기때문에주소가같음 공용체를초기화할때는 { } 안에첫번째멤버의초기값만지정 53
예제 : 공용체의정의및사용 54
공용체의사용예 COLOR_T c1; c1.rgb[0] = 0xFF; // red c1.rgb[1] = 0xAB; // green c1.rgb[2] = 0x1F; // blue c1.rgb[3] = 0x0; // not used printf("rgb color = %08X\n", c1.color); 001FABFF 출력 55
예제 : 공용체를이용한 RGB 색상표현 56
57
참고문헌 천정아, Core C Programming, 연두에디션 (2019) C 가보이는그림책, ANK Co., Ltd., 성안당 (2018) Greg Perry, Dean Miller 어서와 C 언어는처음이지, 천인국옮김, 인피니티북스 (2015) KELLEY ( 역 : 김명호외 ), A Book on C, 홍릉과학출판사 (2003) 윤성우, 열혈 C 프로그래밍, 오렌지미디어 천인국, 쉽게풀어쓴 C 언어 Express, 생능출판사 서현우, 뇌를자극하는 C 프로그래밍, 한빛미디어 강성수, 쾌도난마 C 프로그래밍, 북스홀릭 고응남, C 프로그래밍기초와응용실습, 정익사 58