Microsoft PowerPoint Lec05.ppt [호환 모드]

Similar documents
Microsoft PowerPoint Lec05.ppt [호환 모드]

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

Microsoft PowerPoint - ch07 - 포인터 pm0415

PowerPoint 프레젠테이션

A Dynamic Grid Services Deployment Mechanism for On-Demand Resource Provisioning

목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2

11장 포인터

Microsoft PowerPoint - chap10-함수의활용.pptx

Microsoft PowerPoint - chap06-2pointer.ppt

금오공대 컴퓨터공학전공 강의자료

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

PowerPoint 프레젠테이션

untitled

Microsoft PowerPoint - 제11장 포인터(강의)

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

02장.배열과 클래스

KNK_C_05_Pointers_Arrays_structures_summary_v02

설계란 무엇인가?

11장 포인터

Microsoft PowerPoint - 제11장 포인터

금오공대 컴퓨터공학전공 강의자료

구조체정의 자료형 (data types) 기본자료형 (primitive data types) : char, int, float 등과같이 C 언어에서제공하는자료형. 사용자정의자료형 (user-defined data types) : 다양한자료형을묶어서목적에따라새로운자료형을

Microsoft PowerPoint - chap11-포인터의활용.pptx

슬라이드 1

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

1 장 C 언어복습 표준입출력배열포인터배열과포인터함수 const와포인터구조체컴파일러사용방법 C++ 프로그래밍입문

Microsoft PowerPoint - Chapter_08.pptx

Microsoft PowerPoint - chap-11.pptx

Microsoft PowerPoint - Chapter_09.pptx

제 11 장포인터 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

Microsoft PowerPoint - [2009] 02.pptx

컴파일러

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

Microsoft PowerPoint - ch07 - 포인터 pm0415

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

V28.

문서의 제목 나눔명조R, 40pt

歯7장.PDF

chap7.PDF

비트와바이트 비트와바이트 비트 (Bit) : 2진수값하나 (0 또는 1) 를저장할수있는최소메모리공간 1비트 2비트 3비트... n비트 2^1 = 2개 2^2 = 4개 2^3 = 8개... 2^n 개 1 바이트는 8 비트 2 2

Data Structure

PowerPoint Template

0. 표지에이름과학번을적으시오. (6) 1. 변수 x, y 가 integer type 이라가정하고다음빈칸에 x 와 y 의계산결과값을적으시오. (5) x = (3 + 7) * 6; x = 60 x = (12 + 6) / 2 * 3; x = 27 x = 3 * (8 / 4

chap 5: Trees

OCW_C언어 기초

설계란 무엇인가?

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

이번장에서학습할내용 동적메모리란? malloc() 와 calloc() 연결리스트 파일을이용하면보다많은데이터를유용하고지속적으로사용및관리할수있습니다. 2

C++ Programming

K&R2 Reference Manual 번역본

기초컴퓨터프로그래밍

Microsoft PowerPoint - chap03-변수와데이터형.pptx

Microsoft PowerPoint - ch10 - 이진트리, AVL 트리, 트리 응용 pm0600

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

<4D F736F F F696E74202D20C1A63134C0E520C6F7C0CEC5CD5FC8B0BFEB>

ch15

Microsoft PowerPoint - ch08 - 구조체 (structure) am0845

untitled

ABC 6장

chap7.key

ABC 6장

Microsoft PowerPoint - chap06.ppt

Microsoft PowerPoint - 03_(C_Programming)_(Korean)_Pointers

윤성우의 열혈 TCP/IP 소켓 프로그래밍


13 주차문자열의표현과입출력

Microsoft PowerPoint - chap12-고급기능.pptx

Lab 3. 실습문제 (Single linked list)_해답.hwp

제1장 Unix란 무엇인가?

chap8.PDF

The C++ Programming Language 5 장포인터, 배열, 구조체 5.9 연습문제 다음의선언문을순서대로작성해보자. 문자에대한포인터, 10개정수의배열, 10개정수의배열의참조자, 문자열의배열에대한포인터, 문자에대한포인터에대한포인터, 상수정수, 상수

Microsoft PowerPoint - chap06-5 [호환 모드]


14 주차구조체와공용체

11장 포인터

08년요람001~016

03장.스택.key

Microsoft PowerPoint 자바-기본문법(Ch2).pptx

Chapter 4. LISTS

PowerPoint 프레젠테이션

쉽게 풀어쓴 C 프로그래밍

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

<4D F736F F F696E74202D20C1A63137C0E520B5BFC0FBB8DEB8F0B8AEBFCD20BFACB0E1B8AEBDBAC6AE>

µðÇÃÇ¥Áö±¤°í´Ü¸é

Chapter_06

Microsoft PowerPoint - chap06-8 [호환 모드]

PowerPoint 프레젠테이션

untitled

Infinity(∞) Strategy

PowerPoint 프레젠테이션

<4D F736F F F696E74202D20C1A63132B0AD20B5BFC0FB20B8DEB8F0B8AEC7D2B4E7>

3. 1 포인터란 3. 2 포인터변수의선언과사용 3. 3 다차원포인터변수의선언과사용 3. 4 주소의가감산 3. 5 함수포인터

Microsoft PowerPoint - Chapter14_17.pptx

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어

Microsoft PowerPoint - Lesson14.pptx

Microsoft PowerPoint - Lesson14.pptx

4. 1 포인터와 1 차원배열 4. 2 포인터와 2 차원배열 4. 3 포인터배열 4. 4 포인터와문자그리고포인터와문자열

Microsoft PowerPoint - 05-chap03-ArrayAndPointer.ppt

Transcription:

프로그래밍개론 1 5 장포인터와배열

이장의내용 포인터와주소 포인터와함수인수 포인터와배열 주소연산 문자포인터와함수 포인터배열 - 포인터에대한포인터 다차원배열 문자포인터배열의초기화 포인터배열과다차원배열 명령행인수 함수에대한포인터 2

포인터와주소 포인터 (pointer) 란? 메모리상의주소값을나타내는데이터주소표현방법은컴퓨터에따라다름 Visual Studio 6의 C 언어에서는 32 비트 (4 바이트 ) 정수를이용하여주소를표현하는것으로간주할수있음 변수가나타내는것은무엇인가? 주소? 값? x = y; x 72를 0012FF78번지에저장하라. 0012FF7C번지에들어있는값을 0012FF78 번지에저장하라. = 기호의오른쪽변수의경우저장된값이사용되는반면, 왼쪽변수의경우주소가사용된다. 300 주소 : 0012FF78 y 72 주소 : 0012FF7C 3

포인터와주소 포인터관련단항연산자 & (reference operator): 변수의주소, 즉, 포인터를취한다. p = &c; /* p 에는 c 의주소가저장된다. */ * (de-reference operator): 포인터값앞에오며, 포인터값이가리키는주소에들어있는데이터를취한다. & 의반대역할을한다. c = 3; p = &c; x = *p; /* x에는 3이저장된다. */ 포인터의출력 ( 포맷코드 %p 를사용함 ) printf( %p\n, &x); /* 8 자리 16 진수로출력됨 */ 4

포인터와주소 포인터변수의선언 type *variable; variable 이갖는주소위치에저장되어있는데이터의타입이 type 임을의미한다. 각포인터는특정타입의값을가리킨다. int x = 1, y = 2, z[10]; int *ip; /* ip는정수에대한포인터 */ ip = &x; /* ip 는 x 를가리킨다 */ y = *ip; /* y는 1이된다 */ *ip = 0; /* x의값은0이된다 */ ip = &z[0]; /* ip 는 z[0] 을가리킨다 */ 5

포인터와주소 문장 해설 double *dp; dp는 double 타입의값에대한포인터 double atof(char *); atof() 는문자에대한포인터를인수로취한다 int *ip, *iq; ip와 iq는 int 타입의값에대한포인터 ip = &x; ip는 x를가리킨다 *ip = *ip + 10; x의값이10 증가한다 y = *ip + 1; y는 x+1이된다 *ip += 1; x의값이1 증가한다 ++*ip; x의값이1 증가한다 (*ip)++; x 의값이 1 증가한다 ( 괄호가없으면의미가달라진다 ) iq = ip; iq 도 x 를가리킨다 6

포인터와함수인수 C의값에의한인수전달방식으로인해호출함수에정의된변수를직접적으로변경할수없다. 그러나포인터를사용하여간접적으로호출함수측의변수를변경할수있다. void swap(int x, int y) int temp; temp = x; x = y; y = temp; main() int a = 3, b = 5; x a y 5 3 b 3 5 void swap(int *px, int *py) int temp; temp = *px; *px = *py; *py = temp; main() int a = 3, b = 5; x a &a y &b b 5 3 swap(a, b); printf("a = %d, b = %d", a, b); swap(&a, &b); printf("a = %d, b = %d", a, b); 7

포인터와함수인수 키보드에서정수읽는함수 getint() 만들기 부호를포함하는정수표현이자유형식으로입력된다. 숫자에해당하는문자열을정수로변환하여돌려주고, 또파일끝여부를알려주어야한다. 두가지값의반환이필요하므로리턴값외에값을돌려줄방법이필요하다. ( 포인터타입의매개변수로읽은값리턴 ) #include <stdio.h> #define SIZE 100 main() int i, n, array[size], getint(int *); for (n = 0; n < SIZE && getint(&array[n])!= EOF; n++) ; for (i = 0; i < n; i++) printf("%d%c", array[i], i == n-1? '\n' : ' '); 8

포인터와함수인수 /* p. 61 의 atoi() */ #include <ctype.h> int atoi(char s[]) int i, n, sign; for (i = 0; isspace(s[i]); i++) ; sign = (s[i] == '-')? -1 : 1; if (s[i] == + s[i] == - ) i++; for (n = 0; isdigit(s[i]); ++i); n = n * 10 + (s[i] '0'); 0); return sign*n; #include <stdio.h> #include <ctype.h> int getch(void); int ungetch(int); int getint(int *pn) int c, sign; while (isspace(c = getch())) /* 공백지나가기 */ ; if (!isdigit(c) && c!= EOF && c!= '+' && c!= '-') ungetch(c); /* 숫자아님 */ return 0; sign = (c == '-')? -1 : 1; if (c == '+' c == '-') c = getch(); for (*pn = 0; isdigit(c); c = getch()) *pn = 10 * *pn + (c - '0');') *pn *= sign; if (c!= EOF) ungetch(c); return c; 9

포인터와배열 포인터와배열은아주밀접한관계에있다 a[0] a[1] a[2] a[3] a[4] int a[5], x; int *pa; pa = &a[0]; /* pa는 a[0] 의주소를갖는다 */ x = *pa; /* x = a[0] 에해당된다 */ pa pa+1 pa+2 pa+3 pa+4 포인터와배열의차이 포인터변수가갖는주소값은변경될 이예에서 *(pa + i) 는 a[i] 와수있다. ( 올바른표현 ) 동등한의미로사용될수있다. pa = a pa++ 동등한표현들 pa = a pa = &a[0] a[i] *(a + i) &a[i] a + i pa[i] *(pa + i) 배열이름은배열이시작되는주소를나타내지만, 배열이름이나타내는주소값은변경될수없다.( 틀린표현 ) a = pa a++ sizeof pa는 4인반면sizeof a는 20 이다. (int 의크기는 4 바이트로가정 ) 10

포인터와배열 배열이름을함수의인수로사용할경우, 함수에전달되는것은배열자체가아니라배열의시작주소, 즉, 포인터이다. 즉, 배열에들어있는값들이함수로전달되는것이아니라, 그배열시작주소만을전달한다. 따라서 strlen(s) 와 strlen(&s[0]) 이라는두표현은동등하다. (strlen() 은스트링의길이를알려주는 C 표준함수이다.) 함수 strlen() 의헤딩은아래의두가지표현으로표시될수있으며, 이들은동등한표현이다. int strlen(char s[]); int strlen(char *s); 전역변수나지역변수의정의에서라면 char *s 와 char s[] 는분명서로다른표현이다. 11

포인터와배열 /* 2 장의 strlen() 정의 */ /* 새로운 strlen() 정의 */ int strlen(char s[]) int strlen(char *s) int i; int i; for (i = 0; s[i]!= '\0'; ++i) ; return i; for (i = 0; *s!= '\0'; s++) i++; return i; #include <stdio.h> main() char array[] = "abcd"; char *ptr = array + 1; printf("%d %d %d\n", strlen("hello, world"), strlen(array), strlen(ptr)); 12

포인터연산 포인터와관련하여다음과같은연산이허용된다. 아래에서 p, q는동일한타입의포인터, i는정수라고하자. 포인터 + 정수 : p + i는 p가가리키는원소보다 /* 또다른 strlen() i개만큼뒤에위치하는원소의주소를나타낸다. 정의 */ 포인터 - 정수 : p - i는 p가가리키는원소보다 i개만큼앞에위치하는원소의주소를나타낸다. int strlen(char *s) 포인터 - 포인터 : p - q는 p가가리키는원소와 q가가리키는원소사이에있는원소의개수를 char *p = s; 나타낸다. 보다정확히표현하자면, p = q + i이면 p - q는 i가된다. while (*p!= '\0') 관계연산자에의한두포인터값의비교 : p < q p++; return p - s; 포인터의배정 : p = q 이외에포인터에정수를곱하거나나눈다든지, 또는포인터들끼리의덧셈등은그의미가정의되지않는다. 13

문자포인터와함수 char *pmessage = "now is the time"; 여기서의 "now is the time" 은스트링상수이며, 상수들을저장하는특별한메모리영역에저장된다. 그주소가포인터변수 pmessage 에저장된다. char amessage[] = "now is the time"; 여기서의 "now is the time" 은스트링상수가아니라, 초기화표현 'n', 'o', 'w', ' ',..., 'm', 'e', '\0' 의약식표현이다. 변수저장영역에크기가 16 바이트인배열 amessage 가만들어진다. pmessage: amessage: now is the time\0 now is the time\0 14

문자포인터와함수 ( 스트링복사 ) void strcopy(char *s, char *t) int i; i = 0; while ((s[i] = t[i])!= '\0') i++; /* C 표준함수 */ char *strcpy(char *s, char *t) char *p = s; while (*s++ = *t++) ; return p; void strcopy(char *s, char *t) while ((*s++ = *t++)!= '\0') ; void strcopy(char *s, char *t) while ((*s = *t)!= '\0') s++; t++; while (*s++ = *t++) ; void strcopy(char *s, char *t) 15

문자포인터와함수 ( 스트링비교 ) /* C 표준함수 배열버전 */ /* C 표준함수 포인터버전 */ /* return 음수 if s < t, 0 if s == t 양수 if s > t */ int strcmp(char *s, char *t) int i; for (i = 0; s[i] == t[i]; i++) if (s[i] == '\0') return 0; return s[i] [] t[i]; /* return 음수 if s < t, 0 if s == t 양수 if s > t */ int strcmp(char *s, char *t) for (; *s == *t; s++, t++) if (*s == '\0') return 0; return *s *t; 16

포인터배열 - 포인터에대한포인터 char *a[100]; a 는원소 100 개로이루어진배열 배열 a 의각원소는 char * 타입, 즉, 문자포인터 예제 : 스트링정렬프로그램 defghi 스트링의비교에는 strcmp() 함수사용 모의코드 read all the lines of input sort them using Quick Sort print them in order jklmnopqrst abc defghi jklmnopqrst abc 17

포인터배열 - 포인터에대한포인터 #include <stdio.h> #define MAXLINES 5000 /* 최대행수 */ int readlines(char *lines[], int nlines); void writelines(char *lines[], int nlines); void qsort(char *lines[], int left, int right); main() char *lines[maxlines]; int nlines; if ((nlines = readlines(lines, MAXLINES)) > 0) qsort(lines, 0, nlines-1); writelines(lines, nlines); return 0; else printf("error: no lines or too many lines\n"); return 1; 18

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <string.h> 포인터배열 - 포인터에대한포인터 #define MAXLEN 1000 /* 행최대길이 */ int readlines(char *lines[], int maxlines) int nlines; char line[maxlen]; nlines = 0; while (fgets(line, MAXLEN, stdin)!= NULL) if (nlines >= maxlines) return -1; else lines[nlines++] = strdup(line); td return nlines; void writelines(char *lines[], int nlines) while (nlines-- > 0) fputs(*lines++, stdout); void swap(char *v[], int i, int j) char *temp; temp = v[i]; v[i] = v[j]; v[j] = temp; void qsort(char *v[], int left, int right) int i, last; if (left >= right) return; swap(v, left, (left + right) / 2); last = left; for (i = left + 1; i <= right; i++) if (strcmp(v[i], v[left]) < 0) swap(v, ++last, i); swap(v, left, last); qsort(v, left, last-1); qsort(v, last+1, right); 19

다차원배열 (multi-dimensional array) < 출력결과 > #include <stdio.h> August 15th of 2008 is 228th day of the year main() 08/15/2008 int day_of_year(int year, int month, int day); void month_day(int year, int yearday, int *pmonth, int *pday); int mm, dd; dd = day_of_year(2008, 8, 15); printf("august 15th of 2008 is %d%s day of the year\n", dd, (dd%10 == 1)? "st" : (dd%10 == 2)? "nd" : (dd%10 == 3)? "rd" : "th"); month_day(2008, dd, &mm, &dd); printf("%02d/%02d/%04d\n", mm, dd, 2008); 20

static char daytab[2][13] = 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, /* 비윤년 */ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 /* 윤년 */ ; /* 연 / 월 / 일로부터연중날짜를계산하여리턴한다 */ int day_of_year(int year(int year, int month, int day) int i, leap; leap = year%4 == 0 && year%100!= 0 year%400 == 0; for (i = 1; i < month; i++) day += daytab[leap][i]; return day; /* 연도및연중날짜로부터월 / 일계산 */ void month_day(int year, int yearday, int *pmonth pmonth, int *pday) int i, leap; leap = year%4 == 0 && year%100!= 0 year%400 == 0; for (i = 1; yearday > daytab[leap][i]; i++) yearday -= daytab[leap][i]; *pmonth = i; *pday = yearday; 21

다차원배열 1 차원배열원소의위치 ( 즉, 주소 ) 계산 int a[5]; /* a의주소를 10000번지, w = sizeof(int) 는 4로가정 */ a[0] a[1] a[2] a[3] a[4] 10000 10004 10008 10012 10016 a[i] 의주소 : a 의주소 + w * i 22

다차원 20000 b[0][0] 20004 b[0][1] 20008 b[0][2] 20012 b[0][3] 20016 b[0][4] 배열 20020 b[1][0] 20024 b[1][1] 20028 b[1][2] 20032 b[1][3] 20036 b[1][4] 2 차원배열 20040 b[2][0] 20044 b[2][1] 20048 b[2][2] 20052 b[2][3] 20056 b[2][4] int b[10][5];............... 20180 20184 20188 20192 20196 b[9][0] b[9][1] b[9][2] b[9][3] b[9][4] b[0][j] 의주소 : b의주소 + w * j b1 b[1][j] 의주소 : b 의주소 + 20 + w * j b[2][j] 의주소 : b의주소 + 40 + w * j b[i][j] 의주소 : b의주소 + 20 * i + w * j b의주소 + w * 5 * i + w * j b의주소 + w * (5 * i + j) 23

다차원배열 2 차원배열원소의주소계산 int c[m][n]; /* 원소크기 : w */ c[i][j] 의주소 : c의주소 + w * (N * i + j) 3 차원배열원소의주소계산 int d[l][m][n]; /* 원소크기 : w */ d[i][j][k] 의주소 : d 의주소 + w * (M * N * i + N * j + k) 다차원배열원소의주소계산에서첫번째차원의크기를제외한나머지차원의크기들이필요하다. 함수매개변수로다차원배열이사용될경우에첫번째차원을제외한나머지차원의크기가생략되어서는안된다. f(int daytab[][13])... 24

문자포인터배열의초기화 /* 월이름을리턴한다 */ char *month_name(int name(int mm) static char *name[] = "Illegal l month", "January", "February", "March", "April", "May", "June", "July", "August", "September", " "October", " "November", " "December" " ; return (mm < 1 mm > 12)? name[0] : name[mm]; 25

포인터와다차원배열 int a[10][20]; int *b[10]; a 는 int 타입의 2 차원배열이며, b 는 (int *) 타입의 1 차원배열 a, b 모두에대해 int 원소를나타내는 a[3][4], b[3][4] 와같은표현을사용할수있다. a 는곧바로정수들을저장하기위해사용될수있지만, b 의경우각원소에대해별도의배열지정절차가필요하다. b[0] = (int *) malloc(4*100); b[1] = (int *) malloc(4*20);... b 가나타내는 2 차원정수배열은각행의크기가다를수있다. 26

포인터배열과다차원배열 char *name[] = "Illegal month", "January", "February", "March"; char aname[][15] = "Illegal month", "January", "February", "March"; name: Illegal month\0 January\0 February\0 March\0 aname: Illegal month\0 January\0 February\0 March\0h 0 15 30 45 27

명령행인수 명령행의예 명령행에나타나는인수들을받기위한장치가 main() 함수의매개변수이다. main(int argc, char *argv[])... COPY\0 argv: INF.LOG\0 argc 의값은 3 TEST.DAT\0 28

명령행인수 예제 : echo hello, world #include <stdio.h> < 출력결과 > main(int argc, char *argv[]) int i; hello, world for (i = 1; i < argc; i++) printf("%s%s", argv[i], (i < argc - 1)? " " : "\n"); #include <stdio.h> main(int argc, char *argv[]) while (--argc > 0) printf("%s%s", *++argv, (argc > 1)? " " : "\n"); 29

함수에대한포인터 함수에대한포인터도다른포인터들처럼정의하고, 변수나배열에저장하거나함수인수로사용할수있다. int x; int *p; x 는 int, p 는 int 에대한포인터 int f(char *); int (*pf)(char *); int *g(char *); f 는매개변수로 (char *) 을취하고 int 를리턴하는함수 pf 는매개변수로 (char *) 을취하고 int 를리턴하는함수에대한포인터 g 는매개변수로 (char *) 을취하고 (int *) 를리턴하는함수 30

함수에대한포인터 예제 : 일반화된퀵정렬함수 void * 임의의타입에대한포인터 이타입을갖는변수는아무타입의포인터값이나저장할수있다. 단, 이타입의변수에대해 * 연산을적용할수없다. 즉, 그주소에들어있는데이터를꺼낼수없다. int x = 0x41424344; /* ABCD */ void *p = &x; putchar(*p); /* ERROR */ printf("%x\n", *(int *)p); /* 41424344 */ printf("%c\n", *(char *) p); /* D */ #include <string.h> void swap(void *v[], int i, int j) void *temp; temp = v[i]; v[i] [] = v[j]; [] v[j] = temp; void qsort(void *v[], int left, int right, int (*comp)(void *, void *)) int i, last; if (left >= right) return; swap(v, left, (left + right) / 2); last = left; for (i = left + 1; i <= right; i++) if ((*comp)(v[i], v[left]) < 0) swap(v, ++last, i); swap(v, left, last); qsort(v, left, last-1); qsort(v, last+1, right); 31

#include <stdio.h> #include <string.h> 함수에대한포인터 #include <stdlib.h> int numcmp(char *s1, char *s2) #define MAXLINES 5000 /* 최대행수 */ int readlines(char *lines[], int nlines); double v1, v2; void writelines(char *lines[], int nlines); 예제 : 일반화된퀵정렬함수 void qsort(void *lines[], int left, int right, v1 = atof(s1); int (*comp)(void *, void *)); v2 = atof(s2); int numcmp(char *, char *); if (v1 < v2) return -1; main(int argc, char *argv[]) else if (v1 > v2) return 1; char *lines[maxlines]; else int nlines, numeric = 0; return 0; if (argc > 1 && strcmp(argv[1], "-n") == 0) numeric = 1; if ((nlines = readlines(lines, MAXLINES)) > 0) qsort((void **) lines, 0, nlines-1, (int (*)(void *, void *)) (numeric == 1? numcmp : strcmp)); writelines(lines, nlines); return 0; else... 32

11 주차실습 연습문제 5-2 & 5-5 Exercise 5-2. Write getfloat, the floating-point analog of getint. What type does getfloat return as its function value? Hint) Compare the function atoi() in p. 61 and the function atof() in p. 71. 33

11 주차실습 Exercise 5-5. 5 Write versions of the library functions strncpy, strncat, and strncmp, which operate on at most the first n characters of their argument strings. For example, strncpy(s,t,n) copies at most n characters of t to s. Full descriptions are in Appendix B. char *strncpy(s,ct,n) copy at most n characters of string ct to s; return s. Pad with '\0''s if ct has fewer than n characters. char *strncat(s,ct,n) concatenate at most n characters of string ct to string s, terminate s with '\0'; return s. int strncmp(cs,ct,n) compare at most n characters of string cs to string ct; return <0 if cs<ct, 0 if cs==ct ct, or >0 if cs>ct. 34

11 주차실습 숙제 : 연습문제 5-4 Exercise 5-4. Write the function strend(s,t), which returns 1 if the string t occurs at the end of the string s, and zero otherwise. 35

12 주차실습 연습문제 5-10 & 5-14 Exercise 5-10. Write the program expr, which evaluates a reverse Polish expression from the command line, where each operator or operand is a separate argument. For example, expr234+* evaluates 2 * (3+4). 36

12 주차실습 Exercise 5-14. Modify the sort program to handle a -r flag, which indicates sorting in reverse (decreasing) order. Be sure that r works with -n. 37

프로그래밍개론 1 6 장구조체

이장의내용 구조체기초 구조체와함수 구조체배열 구조체에대한포인터 typedef 공용체 2

구조체기초 struct point int x; int y; ; /* 좌표타입 */ struct point p1, p2; struct point pt = 320, 200; printf("%d %d\n", pt.x, pt.y); p1 = pt; 구조체 (structure) 는한개이상의변수들을포함하며, 이들을하나의이름을사용하여간편하게나타내기위한것이다. 구조체안의변수들의타입은 struct rect 서로다를수도있다. struct point pt1; 구조체는복잡한항목들로구성되는 struct point pt2; 데이터를개별항목들을별도로취급하는대신 ; 전체를한덩어리로취급할수있게함으로써이러한데이터의사용을간편하게해준다. struct rect screen; 구조체안의개별변수를멤버 (member) 또는 screen.pt1.x = 3; 필드 (field) 라고부르며, 프로그램안에서필드를지칭하기위해도트 (.) () 연산자를사용한다. y pt2 point나 rect 등과같은구조체이름은 structure tag라고불리며, 생략될수도있다. pt1 x 3

구조체와함수 구조체관련연산 : 구조체에적용할수있는연산은다음세종류로제한되어있다. 구조체단위의복사또는 assignment: 여기서복사란다음경우를가리킨다. 함수에매개변수로전달되는경우, 함수의결과값으로구조체를리턴하는경우, 구조체변수를이미값이정의된같은타입의구조체변수로초기화하는경우 주소연산자 & 로주소를취하는것. 도트 (.) 연산자를적용하여필드에접근하는것. 구조체단위로비교하거나입출력등은허용되지않는다. 4

구조체와함수 point 및 rect 구조체를리턴값이나매개변수로사용하는예제 /* x, y에서좌표값형성 */ struct point makepoint(int x, int y) struct point temp; temp.x = x; temp.y = y; return temp;... struct rect screen; struct point middle; screen.pt1 = makepoint(0,0); screen.pt2 = makepoint(xmax, YMAX); middle = makepoint( (screen.pt1.x + screen.pt2.x)/2, (screen.pt1.y + screen.pt2.y)/2); /* 두좌표를더한다 */ struct point addpoint (struct point p1, struct point p2) p1.x += p2.x; p1.y += p2.y; return p1; /* 좌표가사각형내부에있는지검사 */ int pt_in_rect (struct point p, struct rect r) return p.x > r.pt1.x && p.x < r.pt2.x && p.y > r.pt1.y && p.y < r.pt2.y; 5

구조체배열 예제 : 각각의 C 키워드의출현빈도를세는프로그램 키워드스트링의배열과빈도배열이필요하다. char *keyword[nkeys]; int keycount[nkeys]; 혹은다음과같은구조체배열을사용할수도있다. struct key char *word; int count; keytab[nkeys]; 구조체배열초기값리스트에서생략된초기값이없을경우안쪽의중괄호들은생략될수있다. struct key char *word; int count; keytab[] = "auto", 0, "break", 0, "case", 0, "char", 0, /*... */ "while", 0 ; 6

구조체배열 #include <stdio.h> #include <ctype.h> #include <string.h> #define NKEYS (sizeof keytab / sizeof(struct key)) #define MAXWORD 100 struct key... keytab[] =... ; int getword(char *, int); int binsearch(char *, struct key *, int); main() int n; char word[maxword]; while (getword(word, MAXWORD)!= EOF) if (isalpha(word[0])) n = binsearch(word, keytab, NKEYS); if (n >= 0) keytab[n].count++; for (n = 0; n < NKEYS; n++) if (keytab[n].count > 0) printf("%4d %s\n", keytab[n].count, keytab[n].word); 7

/* 3 장의코드수정 */ 구조체배열 int binsearch(char *word word, struct key tab[], int n) int cond; int low, high, mid; low = 0, high h = n -1; while (low <= high) mid = (low + high) / 2; cond = strcmp(word, tab[mid].word); if (cond < 0) high = mid - 1; else if (cond > 0) low = mid + 1; else return mid; return -1; int getword(char *word, int lim) int c, getch(void); void ungetch(int); char *w = word; while (isspace(c = getch())) ; if (c!= EOF) *w++ = c; if (!isalpha(c)) ( *w++ = '\0'; return c; for ( ; --lim > 0; w++) if (!isalnum(*w = getch())) ungetch(*w); break; *w = '\0'; return word[0]; 8

구조체에대한포인터 /* 포인터버전 */ #include <stdio.h> #include <ctype.h> #include <string.h> #define NKEYS (sizeof keytab / sizeof(struct key)) #define MAXWORD 100 while (getword(word, MAXWORD)!= EOF) struct key... =... ; if (isalpha(word[0]) int getword(char *, int); p = binsearch(word, keytab, NKEYS); struct key *binsearch if (p!= NULL) (char *, struct key *, p->count++; int); for (p = keytab; p < keytab + NKEYS; p++) main() if (p->count > 0) printf("%4d %s\n", p->count, p->word); char word[maxword]; struct key *p; 9

struct key *binsearch(char *word, 구조체 struct 배열 key *tab, int n) 포인터값 NULL <stdio.h> 에정의되어있다. int cond; struct key *low = &tab[0]; struct key *high h = &tab[n]; 대개 0으로정의되는데, 이는메모리시작주소를 struct key *mid; 의미하는것이아니라사 용불가주소를나타낸다. while (low < high) mid의계산 mid = low + (high - low) / 2; (low + high) / 2는사용할 cond = 수없다. strcmp(word, mid->word); 포인터들끼리의덧셈은정 if (cond < 0) 의되지않기때문이다. high = mid; else if (cond > 0) high low = mid + 1; else 예전에는검색구간의마지막원소를나타냈지만, return mid; 여기서는그다음원소를 가리킨다. return NULL; 10

typedef typedef 는새로운데이터타입정의기능을제공한다. typedef int Length; typedef struct String word; Length len, maxlen; int count; Length *lengths[10]; Key; typedef char *String; String p, lineptr[maxlines]; int strcmp(string, String); Key keytab[nkeys]; Key *binsearch(string word, Key *tab, int n); Key *low; typedef int (*PFI)(String, String); PFI strcmp, numcmp; 11

공용체 (union) 공용체란? union u_tag 두가지이상의서로다른타입의데이터를저장할수있는변수 공용체정의형식은구조체정의형식과거의같다. 멤버에대한접근방식도구조체의경우와같이도트연산자나 -> 등이사용된다. 공용체안의멤버들은동일한영역을차지한다. int ival; double dval; char *sval; u; uival u.ival = 3; u.dval = 12.34; u.sval = "abcdefg"; 오른쪽예에서 u.dval에대한배정문으로인해, u.ival의값이없어진다. 공용체의크기는가장큰멤버에의해정해진다. 12

공용체 struct char *name; int flags; int utype; union int ival; float fval; char *sval; u; symtab[nsym]; if (symtab[i].utype == INT) printf("%d\n", " symtab[i].u.ival); else (symtab[i].utype == FLOAT) printf("%f\n", symtab[i].u.fval); else (symtab[i].utype == STRING) printf("%s\n", symtab[i].u.sval); else printf("bad type %d in utype\n", symtab[i].utype); 13

실습 13 주차 텍스트의 C 키워드출현빈도세기프로그램을확장한다. 어떤식별자들이나타나는지와그출현빈도를센다. 키워드를위한 struct key는다음과같이확장한다. typedef struct char *word; int keyword; /* 일반식별자이면 0, 키워드이면 1 */ int count; Symbol; 새로운식별자가나타나면, 이를위한항을정렬된상태를유지하며추가한다. ( 정렬상태는이진검색을위해필요함 ) 결과출력시키워드빈도를먼저출력하고, 일반식별자를출력한다. 14