Transcript 구조체

9장. 구조체
#include <stdio.h>
int main(void)
{
int num;
printf(“Please enter an integer: ");
scanf("%d", &num);
if ( num < 0 )
printf("Is negative.\n");
printf("num = %d\n", num);
return 0;
}
1
학습목표
■ 구조체란 무엇인지 알아보고, 구조체를 정의하고 사용하는 방법을 알아본다.
■ 구조체 변수를 선언하고 초기화하는 방법을 알아본다.
■ 구조체 배열이나 구조체 포인터를 사용하는 방법을 알아본다.
■ 공용체란 무엇인지 알아보고, 공용체를 정의하고 사용하는 방법을 알아본다.
■ 열거체란 무엇인지 알아보고, 열거체를 정의하고 사용하는 방법을 알아본다.
■ typedef를 정의하는 방법을 알아본다.
9장. 구조체
2
목차
구조체
• 구조체의 기본
• 구조체의 사용
• 비트필드
공용체와 열거체
• 공용체
• 열거체
typedef
• typedef의 정의
• typedef의 사용 목적
9장. 구조체
3
구조체
구조체의 기본
구조체를 사용하면 관련된 변수들을 하나로 묶어서 사용할 수
있다.
9장. 구조체
4
구조체
구조체의 정의
구조체의 정의
struct 키워드가 필요
9장. 구조체
5
구조체
구조체의 정의
구조체의 멤버로 일반 변수뿐만 아니라 배열이나 포인터도 가능
구조체를 정의하는 것은 새로운 데이터 형을 만드는 것이다.
기본 데이터 형 : char, short, int, float, double
파생 데이터 형 : 기본 형으로 만들어 낸 데이터 형(배열, 포인터, 구조체, 공용체,
열거체)
사용자정의형 : 구조체처럼 프로그래머가 새로 만들어진 데이터 형
구조체의 멤버들은 구조체 변수가 선언될 때
메모리에 할당된다.
struct student형의 변수를 선언할 때
name, korea, english, math, average가
메모리에 할당
9장. 구조체
6
구조체
구조체의 크기
구조체의 크기는 모든 멤버의 크기를 더한 만큼일 것이다.
9장. 구조체
7
구조체
 구조체 변수의 선언
구조체 변수의 선언
구조체 변수를 선언하면 메모리에 구조체 변수가 할당되는데,
구조체 변수가 가진 멤버들이 메모리에 순서대로 할당된다.
9장. 구조체
8
구조체
구조체 변수의 사용
구조체의 멤버에 접근할 때는 멤버 접근 연산자인 .을 이용한다.
구조체 변수를 한번에 여러 개 선언
9장. 구조체
9
구조체
구조체 변수의 사용
서로 다른 구조체의 변수
9장. 구조체
10
구조체
구조체 변수의 사용
구조체를 정의하면서 변수를 함께 선언하는 것도 가능
점의 좌표 x, y 멤버로 갖는 point 구조체를 정의하고 변수도 함께 선언한 경우
구조체를 정의하면서 변수도 함께 정의할 때 구조체의 태그명 생략 가능
9장. 구조체
11
구조체
구조체 변수의 초기화
구조체 변수를 선언할 때 초기화하려면 { }를 쓴 다음, { } 안에
멤버들의 초기값을 순서대로 나열한다.
9장. 구조체
12
구조체
구조체 변수의 초기화
만일 { } 안에 지정한 초기값이 멤버의 개수보다 부족하면 나머
지 멤버들은 0으로 초기화
9장. 구조체
13
구조체
구조체 변수의 초기화
student 구조체의 정의 및 사용 예
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
/* Ex09_01.c */
#include <stdio.h>
struct student {
char name[20];
int korean, english, math;
double average;
};
구조체의 정의
int main(void)
{
struct student s1 = {"김모모", 100, 100, 100, 0.0};
struct student s2 = {"박나나", 90, 78, 86};
s1.average = (double)(s1.korean + s1.english + s1.math) / 3;
s2.average = (double)(s2.korean + s2.english + s2.math) / 3;
printf("이름 : %s, 평균 : %5.2f\n", s1.name, s1.average);
printf("이름 : %s, 평균 : %5.2f\n", s2.name, s2.average);
}
구조체 변수의 선언 및 초기화
각 학생의 평균 구하기
각 학생 이름과 평균 출력하기
return 0;
9장. 구조체
14
구조체
구조체 변수의 초기화
point 구조체의 정의 및 사용 예
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
/* Ex09_02.c */
#include <stdio.h>
#include <math.h>
struct point {
int x, y;
};
int main(void)
{
struct point p1, p2;
double dist;
수학 관련 라이브러리 헤더
구조체의 정의
구조체 변수의 선언
9장. 구조체
15
구조체
구조체 변수의 초기화
point 구조체의 정의 및 사용 예
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
printf("p1의 x, y 좌표를 입력하세요 : ");
scanf("%d %d", &p1.x, &p1.y);
구조체 변수의 값 입력
printf("p2의 x, y 좌표를 입력하세요 : ");
scanf("%d %d", &p2.x, &p2.y);
구조체 변수의 값 입력
dist = sqrt( pow(p2.x-p1.x, 2) + pow(p2.y-p1.y, 2) );
두 점 사이의 거리 구하기
printf("두 점 사이의 거리 : %f\n", dist);
}
return 0;
9장. 구조체
16
구조체의 활용
구조체 간의 초기화 및 대입
같은 구조체 형의 변수들끼리는 서로 초기화나 대입이 가능하다
9장. 구조체
17
구조체의 활용
구조체 간의 초기화 및 대입
구조체 간의 초기화 및 대입
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
/* Ex09_03.c */
#include <stdio.h>
struct point {
int x, y;
};
int main(void)
{
struct point
struct point
struct point
struct point
p1 = {10, 20};
p2 = {30, 40};
p3 = p1;
p4;
구조체 변수의 선언 및 초기화
구조체 간의 초기화
printf("p3의 좌표 : %d, %d\n", p3.x, p3.y);
p4 = p2;
구조체 간의 대입
printf("p4의 좌표 : %d, %d\n", p4.x, p4.y);
}
return 0;
9장. 구조체
18
구조체의 활용
 구조체 배열의 선언
구조체 배열을 메모리에 할당하면 구조체 변수들이 메모리에 연
속적으로 할당된다.
9장. 구조체
19
구조체의 활용
 구조체 배열의 사용
구조체 배열도 인덱스를 이용해서 배열의 원소에 접근할 수 있
다.
9장. 구조체
20
구조체의 활용
 구조체 배열의 초기화
구조체 배열을 초기화하려면 { }안에 배열의 원소의 초기값을 나
열하면 된다.
9장. 구조체
21
구조체의 활용
 구조체 배열
구조체 배열을 이용한 성적 처리 프로그램
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
/* Ex09_04.c */
#include <stdio.h>
#define MAX_STD 5
struct student {
char name[20];
int korean, english, math;
double average;
};
int main(void)
{
struct student std[MAX_STD];
int i;
double total_average = 0;
구조체 배열의 크기
구조체의 정의
구조체 배열의 선언
printf("%d 명의 학생 정보를 입력하세요.\n", MAX_STD);
for( i = 0 ; i < MAX_STD ; i++ )
{
9장. 구조체
22
구조체의 활용
 구조체 배열
구조체 배열을 이용한 성적 처리 프로그램
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
}
printf("이름 : ");
scanf("%s", std[i].name);
printf("국어, 영어, 수학 점수 : ");
scanf("%d %d %d",
&std[i].korean, &std[i].english, &std[i].math);
std[i].average = (double)
(std[i].korean + std[i].english + std[i].math) / 3;
total_average += std[i].average;
구조체 배열의 입력
각 학생의 평균 구하기
total_average /= MAX_STD;
printf("\n이름
국어 영어 수학 평균\n");
for( i = 0 ; i < MAX_STD ; i++ )
{
printf("%-10s %3d %3d %3d %6.2f\n",
std[i].name, std[i].korean, std[i].english,
std[i].math, std[i].average);
}
printf("전체 평균 : %6.2f\n", total_average);
}
구조체 배열의 출력
return 0;
9장. 구조체
23
구조체의 활용
 구조체 배열
실행결과
9장. 구조체
24
구조체의 활용
구조체 포인터
구조체 포인터는 구조체 변수를 가리키는 포인터이다.
9장. 구조체
25
구조체의 활용
구조체 포인터
구조체 포인터로 간접 멤버 접근 연산자인 -> 연산자를 사용한
다.
9장. 구조체
26
구조체의 활용
구조체 포인터
구조체 포인터의 사용 예
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
/* Ex09_05.c */
#include <stdio.h>
struct student {
char name[20];
int korean, english, math;
double average;
};
int main(void)
{
struct student s = {"김모모", 100, 100, 100, 0.0};
struct student *p = &s;
구조체 포인터의 선언
(*p).average =
(double)((*p).korean + (*p).english + (*p).math) / 3;
printf("이름 : %s\n", p->name);
printf("평균 : %6.2f\n", p->average);
}
포인터가 가리키는
구조체의 멤버 접근
->를 이용한 구조체의 멤버 접근
return 0;
9장. 구조체
27
구조체
 비트필드
비트필드는 2바이트나 4바이트 크기의 데이터 형을 비트 단위
로 나누어 사용할 수 있게 한다.
비트 필드를 정의할 때는 멤버 이름 다음에 :를 쓰고 비트 수를
적어주면 된다.
비트필드는 첫 번째 멤버를 최하위 비트에서부터 할당한다.
9장. 구조체
28
구조체
 비트필드
비트필드의 멤버는 정해진 비트로 값을 표현하므로 표현 가능한
범위를 넘어서는 값을 저장하면 오버플로우가 발생한다.
9장. 구조체
29
구조체
 비트필드
비트필드의 사용 예
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
/* Ex09_06.c */
#include <stdio.h>
struct time {
unsigned int sec : 6;
unsigned int min : 6;
unsigned int hour : 5;
};
int main(void)
{
struct time t1;
비트필드의 정의
비트필드 구조체 변수의 선언
printf("time 구조체의 크기 : %d\n", sizeof(struct time));
t1.hour = 5;
t1.min = 30;
t1.sec = 70;
비트필드 구조체의 크기
비트필드 멤버의 오버플로우 발생
printf("%02d:%02d:%02d\n", t1.hour, t1.min, t1.sec);
}
return 0;
9장. 구조체
30
구조체
 비트필드
비트필드를 정의할 때는 중간에 일부 비트를 비워두고 멤버를
특정 비트에 할당할 수 있다.
9장. 구조체
31
공용체와 열거체
공용체
여러 멤버들이 메모리를 공유
공용체의 멤버들은 모든 멤버의 주소가 같다.
공용체를 정의하면 새로운 데이터 형이 된다.
9장. 구조체
32
공용체와 열거체
 공용체 변수의 선언 및 초기화
공용체 변수를 메모리에 할당하면 공용체의 멤버들이 모두 같은
주소에 할당된다.
공용체 변수를 초기화할 때는 첫 번째 멤버만 초기화한다.
공용체의 멤버에 접근할 때도 멤버 접근 연산자인 .를 사용한다.
9장. 구조체
33
공용체와 열거체
 공용체 변수의 선언 및 초기화
공용체의 사용 예
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
/* Ex09_07.c */
#include <stdio.h>
union data {
unsigned long dword;
unsigned char byte[4];
};
int main(void)
{
union data d1;
int i;
공용체의 정의
공용체 변수의 선언
printf("data 공용체의 크기 : %d\n", sizeof(union data));
d1.dword = 0x12345678;
printf("d1.dword = %08x\n", d1.dword);
for( i = 0 ; i < 4 ; i++ )
printf("d1.byte[%d] = %02x\n", i, d1.byte[i]);
}
공용체의 크기
공용체의 사용
return 0;
9장. 구조체
34
공용체와 열거체
 공용체 변수의 선언 및 초기화
리틀 엔디안과 빅 엔디안
9장. 구조체
35
공용체와 열거체
공용체 변수의 사용
공용체의 멤버들은 동시에 사용되지 않는다.
9장. 구조체
36
공용체와 열거체
구조체의 공용체의 비교
구조체의 크기는
멤버들의 크기의 합보다
크거나 같다.
공용체의 크기는
가장 큰 멤버의 크기와 같다.
9장. 구조체
37
공용체와 열거체
열거체
열거체
열거 상수
열거형을 정의할 때 { }안에 나열하는 이름
정수형 상수로 처리
9장. 구조체
38
공용체와 열거체
열거체
열거 상수에 값을 지정하려면 열거 상수 이름 다음에 =을 쓰고
열거 상수의 값을 써준다.
열거체 변수의 선언
열거체 변수에는 열거체 정의에 나열된 열거 상수 값 중 하나를 저장해야 한다.
9장. 구조체
39
공용체와 열거체
열거체
열거 상수 중 일부만 값을 지정하면, 나머지는 하나씩 커지는 정
수 값으로 자동 설정
열거체를 정의할 때도 열거체의 태그명 생략 가능
열거 상수만 정수형 상수로 정의
열거체와 열거 상수는 프로그램의 가독성을 향상시킨다.
9장. 구조체
40
공용체와 열거체
열거체
열거체의 사용 예
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
/* Ex09_08.c */
#include <stdio.h>
enum week {sun, mon, tue, wed, thu, fri, sat};
int main(void)
{
enum week weekday;
weekday = mon;
열거체의 정의
열거체 변수의 선언
열거 상수의 사용
switch( weekday )
{
case sun:
printf("일요일입니다.\n");
break;
case mon:
printf("월요일입니다.\n");
break;
9장. 구조체
41
공용체와 열거체
열거체
열거체의 사용 예
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
case tue:
printf("화요일입니다.\n");
break;
case wed:
printf("수요일입니다.\n");
break;
case thu:
printf("목요일입니다.\n");
break;
case fri:
printf("금요일입니다.\n");
break;
case sat:
printf("토요일입니다.\n");
break;
}
}
return 0;
9장. 구조체
42
typedef
 Typedef의 정의
기존에 사용하던 데이터 형에 새로운 이름을 붙이는 기능
9장. 구조체
43
typedef
 Typedef의 정의
구조체나 공용체, 열거체를 정의할 때, typedef를 이용한다.
typedef로 struct point를 POINT로 정의하고 나면, POINT를 데
이터 형으로 사용할 수 있다.
typedef 정의를 한 다음에도 원래의 데이터 형도 그대로 사용할
수 있다.
9장. 구조체
44
typedef
 Typedef의 정의
typedef의 사용 예
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
/* Ex09_09.c */
#include <stdio.h>
struct point {
int x;
int y;
};
typedef struct point POINT;
구조체의 정의
typedef 정의
int main(void)
{
struct point p1 = {10, 20};
POINT p2;
같은 구조체 변수 간의 대입
p2 = p1;
printf("p2의 좌표 : %d, %d\n", p2.x, p2.y);
}
return 0;
9장. 구조체
45
typedef
 typedef의 사용 목적
typedef를 사용하면 이식성을 얻을 수 있다.
9장. 구조체
46
typedef
 typedef의 사용 목적
typedef를 사용하면 가독성을 얻을 수 있다.
9장. 구조체
47
학습정리
구조체
구조체란
서로 다른 데이터 형의 변수들을 하나로 묶어서 사용하는 기능
구조체의 정의
struct student {
char name[20];
int korean, english, math;
double average;
};
구조체 변수의 선언
struct student s1;
구조체의 멤버 접근 : 멤버 접근 연산자(.)를 이용한다.
s1.average = (double)(s1.korean+s1.english+s1.math)/3;
구조체의 초기화 : { }안에 초기값을 나열한다.
struct student s1 = {"김모모", 100, 100, 100, 0.0};
구조체 배열 및 포인터
struct student arr[3];
struct student *p = &s1;
9장. 구조체
48
학습정리
공용체와 열거체
공용체 : 공용체의 멤버들은 모두 같은 주소에 할당되므로 메모리를 공유
union data {
unsigned long dword;
unsigned char byte[4];
};
열거체 : 정수형의 일종으로 변수가 가질 수 있는 값을 열거 상수로 나열
enum week {sun, mon, tue, wed, thu, fri, sat};
typedef
typedef란 : 기존의 데이터 형에 새로운 이름을 만드는 기능
typedef unsigned int UINT;
typedef의 사용목적 : typedef는 이식성과 가독성을 제공
9장. 구조체
49
9장. 구조체
수고하셨습니다.
질문 있습니까?
NEXT Chapter
10장. 함수의 활용
50