13차시 구조체와 리스트 처리 입출력과...

38
13 차시 : 구조체와 리스트 처리 입출력과 운영체제 프로그래밍 실험 13동국대학교 조영석 문서는 나눔글꼴로 작성되었습니다. 설치하기

Upload: others

Post on 14-Feb-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

13차시: 구조체와 리스트 처리 입출력과 운영체제

• 프로그래밍 및 실험

• 제 13주

• 동국대학교 조영석

이 문서는 나눔글꼴로 작성되었습니다. 설치하기

Page 2: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

2

Chapter 10. 구조체와 리스트 처리

10.1 자기참조 구조체

- 자기 자신과 같은 형의 구조체를 포인트하는 포인터 멤버 필드를 갖는 구조체 - 동적 자료구조(dynamic data strutures)

(예) struct list { int data; struct list *next; } a;

next : NULL 또는 다음 list 원소의 메모리 주소를 가짐. NULL 은 list 의 끝.

a

data next → link(연결)

Page 3: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

3

- node의 작성

struct list a, b, c;

a.data = 1;

b.data = 2;

c.data = 3;

a.next = b.next = c.next = NULL;

↑ NULL

1 a

↑ NULL

2 b

↑ NULL

3 c

Page 4: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

4

- node의 연결

a.next = &b;

b.next = &c;

- 연결된 원소의 자료 검색

a.next -> data : 2 (b.data)

b.next -> data : 3 (c.data)

a.next -> next -> data : 3 (c.data)

1 a

2 b

3 c

Page 5: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

5

10.2 선형 연결 리스트(Linear linked-lists)

- 구조체 자료들이 순차적으로 연결됨.

1

2

3

head

Page 6: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

6

(예) "list.h"

#include <stdio.h> #include <stdlib.h>

typedef char DATA;

struct linked_list {

DATA d;

struct linked_list *next;

} ;

typedef struct linked_list ELEMENT;

typedef ELEMENT *LINK;

- 위의 명세들(typedef)은 기억장소를 할당받지 않음.

변수가 선언될 경우에만 기억장소를 할당함.

Page 7: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

7

- 기억장소의 동적할당

(예)

LINK head;

head = malloc(sizeof(ELEMENT));

• ELEMENT type의 기억장소가 동적으로 할당된 후 그 주소가 head에 저장됨.

- linear linked - list의 작성 예

• 'n', 'e', 'w'를 저장하는 linear linked-list

head = malloc(sizeof(ELEMENT));

head

↑ ↑

Page 8: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

8

head -> d = 'n';

head -> next = NULL;

head -> next = malloc(sizeof(ELEMENT));

head -> next -> d = 'e';

head -> next -> next = NULL;

head

↑ n ↑

head

↑ n ↑ ═

head

↑ n ↑ e ↑ ═

Page 9: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

9

head -> next -> next = malloc(sizeof(ELEMENT));

head -> next -> next -> d = 'w';

head -> next -> next -> next = NULL;

head

↑ n ↑ e ↑ w ↑ ═

Page 10: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

10

10.3 리스트 연산

- 기본연산

• 리스트 생성

• 원소 개수 세기

• 원소 탐색

• 두 리스트의 결합

• 원소 삽입

• 원소 삭제

Page 11: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

11

(예) 문자열의 list 변환 - recursion(list는 재귀적으로 정의됨.)

#include "list.h"

LINK string_to_list(char s[]) { LINK head;

if (s[0] == '\0')

return NULL;

else { head = malloc(sizeof(ELEMENT));

head -> d = s[0];

head -> next = string_to_list(s + 1);

return head; } }

Page 12: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

12

문자열 : s

A : call w/ s

B : call w/ s+1

C : call w/ s+2

a b c \0

a b c \0

head

↑ a ↑ ?

head

↑ b ↑ ?

head

↑ c ↑ ?

b c \0

c \0

Page 13: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

13

D : call w/ s+3

return NULL;

C' :

B' :

A' :

head

↑ c ↑

\0

═ head

↑ b ↑ c ↑ ═

head

↑ a ↑ b ↑ c ↑ ═

Page 14: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

14

- (예) 문자열의 list 변환 : repetition(반복)

#include "list.h"

LINK s_to_l(char s[]) { LINK head = NULL, tail; int i;

if (s[0] != '\0') { head = malloc(sizeof(ELEMENT)); /* 1st element */ head -> d = s[0]; tail = head;

for (i = 1; s[i] != '\0'; ++i) { tail -> next = malloc(sizeof(ELEMENT)); tail = tail -> next; tail -> d = s[i]; } tail -> next = NULL; } return head; }

Page 15: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

15

• list w/ one element

• 두번째 element 첨부

• tail의 갱신

head

tail

a ↑ ?

head

tail

a ↑ ? ↑ ?

head

tail

a ↑ b ↑ ?

Page 16: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

16

• 세번째 element 첨부

• tail의 갱신

• '\0'를 발견

head

tail

a ↑ b ↑ ? ↑ ?

head

tail

a ↑ b ↑ c ↑ ?

head

tail

a ↑ b ↑ c ↑

Page 17: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

17

10.4 리스트 처리 함수

- 리스트의 원소의 수를 세는 함수

• 재귀 version

int count(LINK head)

{

if (head == NULL)

return 0; else

return (1 + count(head -> next));

}

Page 18: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

18

• for loop 사용

int count(LINK head)

{

int cnt = 0;

for ( ; head != NULL; head = head -> next)

++ cnt;

return cnt;

}

Page 19: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

19

- 리스트의 원소를 출력

• 재귀 version

void print_list(LINK head)

{

if (head == NULL)

printf("\nNULL");

else {

printf("\n%c --> ", head -> d);

print_list(head -> next);

}

}

Page 20: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

20

- 문자열 "abc"를 list로 바꾸고 그 list를 출력

#include "list.h"

LINK string_to_list(char []); void print_list(LINK); void count(LINK);

void main() { LINK h;

h = string_to_list("abc");

printf("The resulting list is \n");

print_list(h);

printf("\nNumber of elements : %d", count(h));

}

(실행결과)

The resulting list is

a --> b --> c --> NULL

Number of elements : 3

Page 21: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

21

- 두 list의 결합

void concatenate(LINK a, LINK b)

{

assert(a != NULL);

if (a -> next == NULL)

a -> next = b;

else

concatenate(a -> next, b);

}

Page 22: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

22

- 새로운 원소의 삽입 : 고정된 시간 안에 삽입가능.

(c.f. array : 배열의 길이에 비례)

• 삽입전

void insert(LINK p1, LINK p2, LINK q) { assert(p1 -> next == p2);

p1 -> next = q;

q -> next = p2; }

P1

P2

...

q

A ↑ C ↑

B ↑

...

Page 23: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

23

• 삽입 후

P1

P2

...

q

A ↑ C ↑

B ↑

...

Page 24: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

24

- 원소의 삭제

• 삭제 전

/* temp = p -> next; */

p -> next = p -> next -> next;

/* free(temp); */

• 삭제 후

P

... A ↑ C ↑ B ↑ ...

P

... A ↑ C ↑ B ↑ ...

temp

Page 25: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

25

- 리스트의 삭제 : 재귀호출

void delete_list(LINK head) {

if (head != NULL) {

delete_list(head -> next); free(head);

} }

Page 26: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

26

Chapter 11. 입출력과 운영체제

11.1 출력함수 printf()

11.2 입력함수 scanf() 교재 pp. 511~520을 정독할 것.

11.3 fprintf(), fscanf(), sprintf(), sscanf()

- fprintf() : printf()의 file vresion

int fprintf(FILE *fp, const char *format, ... );

• FILE : stdio.h에서 정의

file의 현재 상태를 나타내는 member들을 가지는

특별한 구조체.

• fp가 point하는 file에 내용을 write함.

Page 27: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

27

- fscanf() : scanf()의 file version

int fscanf(FILE *fp, const char *format, ...);

▪ fp가 point하는 file에서 내용을 read함.

- stdin, stdout, stderr

▪ stdio.h에 정의되어 있는 file pointer

▪ stdin : standard input

fscanf(stdin, ...) == scanf( ... )

▪ stdout : standard output

fprintf(stdout, ...) == printf( ... )

▪ stderr : standard error

fprintf(stderr, ...) == printf( ... )

Page 28: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

28

- sprintf() : printf()의 문자열 version

▪ int sprintf(char *s, const char *format, ...);

s(문자열)에 format에서 정의된 대로 출력

- sscanf() : scanf()의 문자열 version

▪ int sscanf(const char *s, const char *format, ...),

s(문자열)에서 format에 정의된 대로 입력

Page 29: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

29

(예) char str1[] = "1 2 3 go", str2[100], tmp[100];

int a, b, c;

sscanf(str1, "%d%d%d%s", &a, &b, &c, tmp);

sprintf(str2, "%s %s %d %d %d\n", tmp, tmp, a, b, c);

printf("%s", str2);

(실행결과)

a b c tmp

go go 1 2 3

1 2 3 g o \0 • • •

Page 30: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

30

11.4 fopen()과 fclose()

- file : 문자들의 stream

- file의 특징

• 이름을 가짐

• 열리고(open) 닫힘(close)

• 읽혀지고, 씌여지고, 첨부될수 있음

• open 된 후 access가 가능 함

• 우발적인 오용은 막기위해 open하는 목적은 밝혀야 함.

(읽기 : "r", 쓰기 : "w", 첨부 : "a")

Page 31: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

31

(예)

#include <stdio.h>

int main( ) { int a, sum = 0; FILE *ifp, *ofp; ifp = fopen("my_file", "r"); ofp = fopen("output_file", "w");

...

}

• "my_file"을 읽기 전용으로 open 하고

"output_file"을 쓰기 전용으로 open

Page 32: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

32

(예)

while (fscanf(ifp, "%d", &a) == 1)

sum = sum + a;

fprintf(ofp, "The sum is %d.\n", sum);

fclose(ifp);

fclose(ofp);

Page 33: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

33

• open mode

• 읽을수 없거나 쓸수 없는 file(존재하지 않는 file)을 open 하는 경우 fopen() 함수는 NULL을 return함.

모드 의 미

"r" 읽기 위해 문서 파일 열기

"w" 쓰기 위해 문서 파일 열기

"a" 첨부하기 위해 문서 파일 열기

"rb" 읽기 위해 이진 파일 열기

"wb" 쓰기 위해 이진 파일 열기

"ab" 첨부하기 위해 이진 파일 열기

모드 의 미

"r+" 읽기와 쓰기 위해 문서 파일 열기

"w+" 쓰기와 읽기 위해 문서 파일 열기

• • •

Page 34: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

34

(예) copy a file to another

#include <stdio.h> main() { FILE *infile, *outfile; int ch;

printf("This program copies one file to another.\n");

infile = fopen("Old_File.txt", "r"); outfile = fopen("New_File.txt", "w");

while ((ch = getc(infile)) != EOF) putc(ch, outfile);

fclose(infile); fclose(outfile); }

Page 35: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

35

(예) copy a file to another

#include <stdio.h> void CopyFile(FILE *infile, FILE *outfile); main() { FILE *infile, *outfile; printf("This program copies one file to another.\n"); infile = fopen("Old_File.txt", "r"); outfile = fopen("New_File.txt", "w"); CopyFile(infile, outfile); fclose(infile); fclose(outfile); }

void CopyFile(FILE *infile, FILE *outfile) { int ch; while ((ch = getc(infile)) != EOF) { putc(ch, outfile); } }

Page 36: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

36

11.5 예제 : 파일에서의 한 줄 띄어쓰기 #include <stdio.h> #include <stdlib.h> void double_space(FILE *, FILE *); void print_info(char *); void main(int argc, char **argv) { FILE *ifp, *ofp; if (argc != 3) { print_info(argv[0]); exit(1); } ifp = fopen(argv[1], "r"); ofp = fopen(argv[2], "w"); double_space(ifp, ofp); fclose(ifp); fclose(ofp); }

Page 37: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

37

void double_space(FILE *ifp, FILE *ofp) { int c; while((c = getc(ifp)) != EOF) { putc(c, ofp); if(c == '\n') putc('\n', ofp); /* double space */

} } void print_info(char *pgm_name) { printf("\n%s%s%s\n\n%s%s\n\n",

"Usage", pgm_name, "The contents of infile will be" "double-spaced", "and written to outfile."); }

Page 38: 13차시 구조체와 리스트 처리 입출력과 운영체제contents.kocw.net/KOCW/document/2014/dongguk/choyoungsuk1/13.pdf · Chapter 10. 구조체와 리스트 처리 10.1

이 문서는 나눔글꼴로 작성되었습니다. 설치하기

감사합니다.