1 / 45

C 언어 및 실습 C Language and Practice

C 언어 및 실습 C Language and Practice. Chap 8. 배열과 포인터 ( II ). 단원의 개요. 단원의 학습목표. 학습 유의점. 1. C 에서 사용되는 포인터의 개념과 원리에 대해 알아본다 . 2. C 에서 포인터를 선언하는 방법에 대해 알아본다 . 3. 포인터와 배열의 차이점과 유사성에 대해 알아본다 . 4. 함수의 인자로서 포인터 를 사용할 때 코딩 방법과 처리 규칙을 이해한다 . 5. 문자 포인터와 문자열의 배열을 선언하고 활용방법 에 대해 알아본다 .

damian-lott
Download Presentation

C 언어 및 실습 C Language and Practice

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언어 및 실습C Language and Practice Chap 8. 배열과 포인터( II )

  2. 단원의 개요 단원의 학습목표 학습 유의점 1. C에서 사용되는 포인터의 개념과 원리에 대해 알아본다. 2. C에서 포인터를 선언하는 방법에 대해 알아본다. 3. 포인터와 배열의 차이점과 유사성에 대해 알아본다. 4. 함수의 인자로서 포인터를 사용할 때 코딩 방법과 처리 규칙을 이해한다. 5. 문자 포인터와 문자열의 배열을 선언하고 활용방법에 대해 알아본다. 6. 명령어 라인 인수를 선언하고 활용하는 방법을 알아본다. 1. 기억장소의 번지를 중심으로 포인터의 개념을 이해한다. 2. 포인터는 변수로서 간접 연산자를 이용하여 기억 장소의 자료값을 가리키는 것을 이해한다. 3. 포인터는 변수이므로 증가 또는 감소 연산이 가능하지만, 배열은 상수이므로 연산이 불가함을 이해한다. 4. 포인터를 함수 인자로 사용해야 되는 분야를 이해한다. 5. 문자 포인터와 문자열의 배열을 이해한다. 6. 명령어 라인 인자로 포인터를 사용하는 법을 이해한다. 단원의 학습계획 사용된 함수와 선행처리기 1. 함수에 대한 함수 주소를 포인터 변수에 저장하는 방 포인터 법을 이해한다. 2. 포인터 배열 포인터로 구성된 포인터 배열에 대해 이해한다. 3. 포인터의 포인터 포인터의 포인터를 사용하는 이유와 형식에 대해 파악한다. • 함 수 : void func(int*, int* ) : 형 식 : fun(&x, &y); double square(double x ) : 형 식 : square(double x);

  3. 1000 3000 xx x 1004 3004 yy y 함수와 포인터 • 함수에서 두 개 이상의 자료를 반환할 수는 없다(2이상의 인수전달). ☞ 인수로서 포인터 변수를 사용하면 복수 개의 자료를 호출 프로그램으로 반환할 수 있다. (Call by Address) • 실재 반환 값이 반환되어 처리되는 것이 아니라 포인터를 사용하여 두 개 이상의 값을 처리하는 효과를 가짐 #include<stdio.h> void func(int * xx, int* yy); void main() { int x, y; func(&x, &y); printf(“x=%d, y=%d\n”, x, y); } 변수 X, y의 주소 &x, &y를 전달 void func(int * xx, int* yy) { *xx = 8; *yy = 9; } 1000 8 1004 9 호출 프로그램으로 복수 자료의 반환

  4. 1000 3000 xx x 1004 3004 yy y 함수와 포인터 • 함수에서 두 개 이상의 자료를 반환할 수는 없다. ☞ (인수를 포인터 변수로 사용하면 복수 개의 자료를 호출 프로그램으로 반환할 수 있다. (Call by Address) • 실재 반환 값이 반환되어 처리되는 것이 아니라 포인터를 사용하여 두 개 이상의 값을 처리하는 효과를 가짐 #include<stdio.h> void fun(int *xx, int *yy); void main() { int x, y; fun(&x, &y); printf(“x=%d, y=%d\n”, x, y); } 변수 X, y의 주소 &x, &y를 전달 void fun(int *xx, int *yy) { *xx = 8; *yy = 9; } 형식인수 xx와 yy에 실인수의 값을 복사 xx에 저장된 번지(1000) 인 x에 8을 대입 yy에 저장된 번지(1004) 인 y에 9를 대입 1000 1000 8 1004 1004 9 호출 프로그램으로 복수 자료의 반환 [&x,&y : 변수x,y의 주소]

  5. 3000 xx 3004 yy 함수와 포인터 #include<stdio.h> void func(int *xx, int *yy); void main() { int x, y; printf("main() : x번지_&x = %d, y번지_&y = %d\n\n", &x,&y); func(&x, &y); printf("main() : x = %d, y = %d\n\n", x, y); } void func(int * xx, int * yy) { printf("func() : xx = %d, yy = %d\n", xx, yy); *xx = 8; printf("func() : *xx = *(%d) = %d \n", xx, *xx); *yy = 9; printf("func() : *yy = *(%d) = %d \n\n", yy, *yy); } 4521376 8 4521376 4521364 x 9 4521364 y

  6. 함수에 대한 포인터 • 함수 주소를 포인터 변수에 저장 • 포인터 변수가 참조될 때마다 함수를 호출하는 것과 동일한 효과가 발생 • 함수 포인터를 사용하기 위한 선언의 일반 형식 : 예) double (*squp)(double); squp= squ; //함수 squ( ) 표기법 : 자료형(*포인터명)(인수 리스트) ex) int ( *squp) ( int ) 포인터가 가리키는 함수가 취하는 정수형 인수 리스트 포인터가 가리키는 함수의 반환값의 자료형 3가지 함수호출 방법 (1) squ(x); /* 함수명으로 호출 */ (2)squp =squ; squp(x); /* 함수포인터로 호출 */ (3) squp= squ; (*squp)(x) ; /* 함수자체로 호출 */ Main() { ….. squ(x);} //함수명 함수 포인터 squp doublesqu(double x) { : : } 1000 ⑴ squ() 함수호출 1000번지 ⑵ 함수포인터 호출

  7. 함수에 대한 포인터 • 함수 주소를 포인터 변수에 저장 • 함수 포인터가 가리키고 있는 함수를 호출하는 방법의 일반 형식 : • 함수명 대신에 (*포인터명) 또는포인터명(인수 리스트)으로 쓸 수 있음(같은 결과를 얻음) • 함수( squ( )) 에 대한 포인터 개념 표기법 : (*포인터명)(인수 리스트) cf. ( 포인터명)(인수 리스트) == 포인터명(인수 리스트) == 함수명(인수리스트) * (*squp)(x) squp(x) squ(x) squ(x)==(*squp)(x) == squp(x)

  8. 함수에 대한 포인터(함수명, 함수포인터, 함수자체-호출 프로그램의 예) #include <stdio.h> // (2) 함수포인터(squp)로호출 double squ(double x); void main() { double x; double (*squp)(double); x=3.0; squp = squ; // squ()의위치_번지를함수포인터(squp)에저장 printf("squp함수포인터의위치_번지(주소) = %d\n", squp); printf("squp 함수포인터를 사용한 호출결과 = %lf\n\n", squp(x)); } double squ(double x) { return(x*x); } #include <stdio.h> // (1) 함수명(squ() )으로호출 double squ(double x); void main() { double x; x=3.0; printf("squ함수의위치_번지(주소) = %d \n", squ); printf("함수이름을사용한 호출결과= %lf \n\n", squ(x)); } double squ(double x) { return(x*x); }

  9. 함수에 대한 포인터(함수명, 함수포인터, 함수자체-호출 프로그램의 예) #include <stdio.h> // 함수명, 함수포인터, 함수그자체호출: 3가지방법의 각 결과 double squ(double x); void main() { double x; double (*squp)(double); x=3.0; squp = squ; // squ, squp, *squp각위치_번지는모두같음 printf("squ함수의위치_번지(주소) = %d\n", squ); printf("squp함수포인터인주소 = %d\n", squp); printf("(*squp) 함수그자체를가리키는주소= %d\n\n", *squp); /* x=3.0일때3가지함수호출방법에의한결과는모두값음*/ printf("함수이름사용한호출결과 = %lf\n", squ(x) ); /* 함수이름사용*/ printf("함수포인터사용한호출결과= %lf\n", squp(x) ) ; /* 함수포인터사용*/ printf("함수그자체사용한호출결과= %lf\n\n", (*squp)(x) ); /* 함수그자체사용*/ } double squ(double x) { return(x*x); } #include <stdio.h> // (3) 함수 그자체(*squp)를 이용한호출 double squ(double x); void main() { double x; double (*squp)(double); x=3.0; squp = squ; // squ()의위치_번지를함수포인터(squp)에저장 printf("(*squp) 함수그자체를 가리키는 위치_번지(주소) = %d\n", *squp); printf("(*squp) 함수그자체를 사용한 호출결과= %lf\n\n", (*squp)(x) ); } double squ(double x) { return(x*x); }

  10. 10 b[0][0] 20 b[0][1] 30 b[1][0] 40 b[1][1] 50 b[2][0] 60 b[2][1] 다차원 배열과 포인터 • 다차원 배열과 포인터 • 다차원 배열인 경우에도 포인터를 이용해서 각 원소를 참조할 수 있다. • 일반 형식 : • 보기 7-7 • 이차원 배열은 ‘배열의 배열’과 같으므로 아래 그림에서 b가 전체 이차원 배열의 주소를 나타내는 포인터 상수라면 b[i]는 i행의 시작주소를 갖는다. 자료형 (*포인터_변수명) [열의 개수] int b[3][2] ={ {10,20}, {30,40}, {50,60} }; int(*pb)[2]; /* pb는 열의 수가 2인 2차원 배열에 대한 포인터 */ pb=b; b(배열명) *pb[1] *pb[0] pb pb b[0] b[1] b[2] b[0][0] b[0][1] b[1][0] b[1][1] b[2][0] b[2][1] { {10, 20}, {30, 40}, {50, 60} }; 배열 b의 시작번지(&b[0][0]) 임 포인터변수에 배열의 시작주소 대입: pb = &ia[0][0] 또는 pb = b

  11. 다차원 배열과 포인터 #include <stdio.h> void main() { inti,j; int k=0; int b[3][2] ={ {10,20}, {30,40}, {50,60} }; int (*pb)[2]; // pb는2차원배열에대한포인터변수로선언 pb=b; // 배열명(b)자체가 배열의시작주소임 printf("2차원b배열의초기값을포인터변수(pb)와배열(b)를이용하여참조해본다\n"); printf(" *((*pb)+0) =%d b[0][0] =%d\n", *((*pb)+0), b[0][0]); printf(" *((*pb)+1) =%d b[0][1] =%d\n", *((*pb)+1), b[0][1]); printf(" *((*pb)+2) =%d b[1][0] =%d\n", *((*pb)+2), b[1][0]); printf(" *((*pb)+3) =%d b[1][1] =%d\n", *((*pb)+3), b[1][1]); printf(" *((*pb)+4) =%d b[2][0] =%d\n", *((*pb)+4), b[2][0]); printf(" *((*pb)+5) =%d b[2][1] =%d\n\n", *((*pb)+5), b[2][1]); printf("2차원b배열의시작주소== %d, 배열포인터pb == %d \n\n", b, pb); for(i=0; i<3; i++) { // 배열b의 0,1,2 행 k++; // 포인터변수pb의 0,1,2 증가값 printf("b[%d]의저장번지== %d, 현재배열포인터(pb) == %d \n", i, &b[i], pb); for(j=0; j<2; j++) { // 배열b 의0,1 열 printf("%d행의b[%d]이가리키는기억장소b[%d][%d]의값 =%d\n",k,i,i,j,b[i][j]); printf("%d행의(pb)이가리키는기억장소(*pb)[%d]의값 =%d\n",k,j,(*pb)[j]); printf("%d행의(pb)이가리키는기억장소(*pb)+%d의값=%d\n\n",k,j,*((*pb)+j)); } pb++; printf("pb++ \n\n"); } }

  12. 포인터의 배열 • 포인터 배열 : 여러 개의 포인터 변수로 구성된 배열 • C언어에서는 문자열 배열이 따로 존재하지 않음 !!!! • 일반 형식 • 포인터 배열의 특징 • 포인터 배열은 선언과 초기화를 일괄적으로 할 수 있다. char *menu[4] = { “insert”, “change”, “delete”, “search”}; menu[0]; // 문자열 “insert”가 저장된 장소의 시작 주소를 가리킨다[시작주소가 저장됨]. menu[1]; // 문자열 “change”가 저장된 장소의 시작 주소를 가리킨다[시작주소가 저장됨]. menu[2]; // 문자열 “delete”가 저장된 장소의 시작 주소를 가리킨다[시작주소가 저장됨]. menu[3]; // 문자열 “search”가 저장된 장소의 시작 주소를 가리킨다[시작주소가 저장됨]. 표기법 : 자료형 *포인터배열변수[크기]; char *menu[3]; // *menu[0], *menu[1], *menu[2], *menu[3] 4개 배열요소로 구성된 배열

  13. 포인터의 배열 • 포인터 배열의 특징 • 포인터 배열은 고정길이 뿐 아니라 가변길이의 문자열들의 배열을 나타낼 때 유리하다. char *menu[3] = { “ins”, “ch”, “del”}; 포인터 배열의 메모리 구조

  14. 100 103 menu[0] 50 102 101 104 105 menu[1] 54 menu[2] 58 106 110 107 109 108 ‘i’ ‘n’ ‘s’ ‘\0’ ‘c’ ‘h’ ‘\0’ ‘d’ ‘e’ ‘l’ ‘\0’ 포인터의 배열 • 포인터 배열의 특징 • 포인터 배열은 고정길이 뿐 아니라 가변길이의 문자열들의 배열을 나타낼 때 유리하다. 100 104 107 char *menu[3] = { “ins”, “ch”, “del”}; : : 62 포인터 배열의 메모리 구조

  15. 포인터의 배열 #include <stdio.h> void main() { inti; char *menu[3] = {"ins","ch","del"}; //menu[0],menu[1],menu[2]의 위치_번지는 입력된문자수보다큰자리수(4의배수)로 부여됨 printf("menu 배열의시작주소[번지] = %d \n\n", menu[0] ); // 배열과 배열의포인터는menu임 for(i=0; i<3; i++) { printf("menu[%d]에 저장된번지=%d\n", i, *(&menu[i])); printf("배열menu[%d]가 가리키는 기억장소의값= %s\n",i, menu[i]); printf("배열포인터menu+%d가 가리키는 기억장소의값= %s\n\n",i, *(menu+i)); } } char *menu[4] = {"insert","change","delete","search"}; //menu[0],menu[1],menu[2], menu[3]의위치_번지는입력된문자수보다큰자리수로부여됨 for(i=0; i<4; i++) {

  16. 포인터의 포인터 • 포인터의 포인터 : 가리키는 대상이 포인터인 포인터 변수를 지칭 • 포인터의 포인터를 써야 하는 이유 1. 인수가 포인터 배열인 함수를 작성하기 위해 2. 명령행 인수(command-line argument)를 사용하기 위해 • 포인터의 포인터의 일반 형식 • 포인터의 단계는 제한되어 있진 않지만 보통 삼중 포인터까지 사용 표기법 : 자료형**포인터변수/* 이중 포인터 변수 */ 자료형***포인터변수 /* 삼중 포인터 변수 */ ex) char **double_p; /* 이중 포인터 변수 double_p*/ int***triple_p; /* 삼중 포인터 변수 triple_p*/

  17. 정수형 포인터변수 pa 변 수 포인터의 포인터변수(이중포인터변수 ppa) 3 a a p a p * p * * i i i n n n t t t 포인터의 포인터-42페이지 참조 • 이중 포인터(포인터의포인터)변수 의 개념 • 보기 8-3 int*pa , a=3 ; int**ppa ; pa = &a ; // <- pa의 초기화 ppa = &pa ; // <- 이중 포인터의 초기화 &a &pa 그림 이중 포인터의 개념도

  18. 정수형 포인터변수(pa) 변 수 포인터의 포인터변수(이중포인터변수 ppa) 3 a a p a p * p * * i i i n n n t t t 포인터의 포인터 • 이중 포인터의 개념 • 보기 8-3 int*pa , a=3 ; int**ppa ; pa = &a ; // <- pa의 초기화 ppa = &pa ; // <- 이중 포인터의 초기화 a=3 *pa=3 **ppa =3 --- 그림 이중 포인터의 개념도 --- &a(4521520) &pa(4521544) 4521532 4521544 ppa 4521520번지 4521544번지 4521532번지 4531544 4521520 pa 4521520 **ppa =3 3 a *pa=3

  19. 포인터의 포인터 #include <stdio.h> void main() { int *pa; // 단일포인터변수로 pa를 선언 int **ppa; // 이중포인터변수로 ppa를 선언 int a=3; pa = &a; // 변수a의 저장위치를 포인터변수 pa에 대입 ppa = &pa; // 포인터변수pa의 저장위치를 이중포인터변수 ppa에 대입 printf("변수a에 저장된값= %d \n", a); printf("변수a의 저장위치= %d \n",&a); printf("포인터변수pa의 저장위치= %d\n", &pa); printf("포인터변수ppa의 저장위= %d\n\n", &ppa); printf("포인터변수pa에저장된번지(즉,변수a의저장위치) = %d\n", pa); printf("*pa: 단일포인터변수가가리키는(변수a)의값 = %d\n\n", *pa); printf("포인터변수ppa에저장된번지(포인터변수pa의저장위치) = %d\n", ppa); printf("포인터변수pa에저장된번지(변수a의저장위치) = %d\n", pa); printf("**ppa :이중포인터변수가가리키는(변수a)의값 = %d\n\n", **ppa); }

  20. 정수형 포인터변수 pa 변 수 정수형 포인터변수ppa(이중포인터변수가아님) 3 a a p a p * p * i i i n n n t t t 포인터의 포인터 • 이중 포인터의 개념 • 앞에서 보인 이중 포인터 변수(ppa)를 단순 포인터변수로 선언한 경우? int *pa , a=3 ; int *ppa; pa = &a ; // <- pa의 초기화 ppa = &pa ;// <- ppa의 초기화 그림 이중 포인터의 개념도 &pa &a

  21. 정수형 포인터변수ppa • (이중포이터변수가아님) 정수형 포인터변수 pa 변 수 3 a a p a p * p * i i i n n n t t t 포인터의 포인터 • 이중 포인터의 개념 • 앞에서 보인 이중 포인터 변수를 단순 포인터변수로 선언한 경우? int*pa , a=3 ; int*ppa ; pa = &a ; // <- pa의 초기화 ppa = &pa ; // <- ppa의 초기화 a=3, *pa=3, *ppa=3669176 -- -- 3669188 3669200 ppa 그림이중 포인터의 개념도 3669200 3669176 &a(3669176) &pa(3669200) pa 3669176 3 a 3669188번지 3669176번지 3669200번지 *ppa의 값은 3669176이다. ppa에 저장된 값은 포인터 변수 pa의 저장주소(&pa)인3669200으로 이 위치에 있는 값(3669176)을 얻게 된다. **ppa의 값을 찾을 경우 다음과같은 에러가 발생함 // c(21) : error C2100: 간접참조가잘못되었습니다.

  22. 포인터의 포인터 #include <stdio.h> // 이중포인터변수가 아니고 * ppa의값을 알고자 할 때 void main() { int *pa; // 단일포인터변수로pa를선언 int *ppa; // 이중포인터 int **ppa가 아니라 단일포인터변수로ppa를선언 int a=3; pa = &a; // 변수a의저장위치를포인터변수pa에대입 ppa = &pa; // 포인터변수pa의저장위치를이중포인터변수ppa에대입 printf("변수a에저장된값 = %d \n", a); printf("변수a의저장위치 = %d \n",&a); printf("포인터변수pa의저장위치 = %d\n", &pa); printf("포인터변수ppa의저장위치= %d\n\n", &ppa); printf("포인터변수pa에저장된번지(즉,변수a의저장위치) = %d\n", pa); printf("*pa: 단일포인터변수pa가가리키는(변수a)의값 = %d\n\n", *pa); printf("포인터변수ppa에저장된번지(포인터변수pa의저장위치) = %d\n", ppa); printf("포인터변수pa에저장된번지(변수a의저장위치) = %d\n", pa); printf("*ppa :이중포인터변수ppa가가리키는(포인터변수pa)의값= %d\n\n", *ppa); } #include <stdio.h> void main() { int *pa; // 단일포인터변수로pa를선언 int *ppa; // 이중포인터변수로 int **ppa을잘못하여 *ppa로 선언하다면.. int a=3; pa = &a; // 변수a의저장위치를포인터변수pa에대입 ppa = &pa; // 포인터변수pa의저장위치를이중포인터변수ppa에대입 printf("변수a에 저장된값= %d \n", a); printf("변수a의 저장위치= %d \n",&a); printf("포인터변수pa의 저장위치= %d\n", &pa); printf("포인터변수ppa의저장위취= %d\n\n", &ppa); printf("포인터변수pa에저장된번지(즉,변수a의저장위치) = %d\n", pa); printf("*pa: 단일포인터변수가가리키는(변수a)의값 = %d\n\n", *pa); printf("포인터변수ppa에저장된번지(포인터변수pa의저장위치) = %d\n", ppa); printf("포인터변수pa에저장된번지(변수a의저장위치) = %d\n", pa); printf("**ppa :이중포인터변수가가리키는(변수a)의값 = %d\n\n", **ppa); } // >..c(9) : warning C4047: '=' : 'int *'의간접참조수준이'int **'과(와) 다릅니다. // c(21) : error C2100: 간접참조가잘못되었습니다. // 19pp의 프로그램처럼 이중포인터를 선언해야 한다.

  23. 번지(&) 연산자 와 간접(*) 연산자 : : 50 ptr int *ptr ; int a = 3, b = 5; int *ptr ; 3 100 5 a 104 b 포인터 정리 • 포인터 관련 연산자 ( &, * ) • 포인터변수 선언 • 변수 선언 • 포인터 변수에 변수의 번지를 대입 • 포인터 변수가 가리키는 기억 장소의 자료에 접근 104 int *ptr ; int a = 3, b = 5; ptr = &b ; a = *ptr; // a =5 int *ptr ; int a = 3, b = 5; ptr = &b ; 5

  24. 포인터 정리( a값을 b에 대입: 포인터를 이용한 프로그램의예) #include <stdio.h> // b의 값을 a에 저장하시오 void main() { int *ptr; int a=3, b=5; printf("변수선언후, 변수a = %d, 변수b = %d\n", a,b); a=b; printf("b의 값(5)을 a에 대입후 a의 값 = %d\n", a); printf("최종수행후, 변수 a = %d, 변수 b = %d\n\n", a,b); } #include <stdio.h> // 포인터변수를 이용한 변수 b의 값을 변수 a에 저장하시오 void main() { int *ptr; int a=3, b=5; printf("변수선언후, 변수a = %d, 변수b = %d\n", a,b); ptr = &b; printf("포인터변수(ptr)에 변수b의번지를대입후, ptr에 저장된번지= %d\n", ptr); a = *ptr; printf(" ptr이 가리키는 위치(&b)의 값(5)을 a에 대입후 a의 값 = %d\n", a); printf("최종수행후, 변수 a = %d, 변수 b = %d\n\n", a,b); }

  25. 실 습

  26. 단원의 개요 단원의 학습목표 학습 유의점 1. C에서 사용되는 포인터의 개념과 원리에 대해 알아본다. 2. C에서 포인터를 선언하는 방법에 대해 알아본다. 3. 포인터와 배열의 차이점과 유사성에 대해 알아본다. 4. 함수의 인자로서 포인터를 사용할 때 코딩 방법과 처리 규칙을 이해한다. 5. 문자 포인터와 문자열의 배열을 선언하고 활용방법에 대해 알아본다. 6. 명령어 라인 인수를 선언하고 활용하는 방법을 알아본다. 1. 기억장소의 번지를 중심으로 포인터의 개념을 이해한다. 2. 포인터는 변수로서 간접 연산자를 이용하여 기억 장소의 자료값을 가리키는 것을 이해한다. 3. 포인터는 변수이므로 증가 또는 감소 연산이 가능하지만, 배열은 상수이므로 연산이 불가함을 이해한다. 4. 포인터를 함수 인자로 사용해야 되는 분야를 이해한다. 5. 문자 포인터와 문자열의 배열을 이해한다. 6. 명령어 라인 인자로 포인터를 사용하는 법을 이해한다. 단원의 학습계획 사용된 함수 선행처리기 1. 함수와 포인터 함수의 인자로 포인터를 사용해야 하는 분야와 사용법을 알아본다. 2. 함수에 대한 함수 주소를 포인터 변수에 저장하는 방 포인터 법을 이해한다. 3. 포인터 배열 포인터로 구성된 포인터 배열에 대해 이해한다. 4. 포인터의 포인터 포인터의 포인터를 사용하는 이유와 형식에 대해 파악한다. • 함 수 : strlen( ) : 형 식 : strlen(const char*); • 헤더파일 : # include string.h: 함 수 : strlen(const char*);

  27. #include <stdio.h> void convert(float *, float *); void main() { float subj_1, subj_2; convert(&subj_1, &subj_2); printf("\n컴퓨터 개론의 점수는 %.1f점 입니다.\n", subj_1); printf("C언어및실습의 점수는 %.1f점 입니다.\n", subj_2); } void convert(float *xx, float *yy) { float x, y; printf("컴퓨터 개론의 점수는? "); scanf("%f", &x); printf("C언어및실습의 점수는? "); scanf("%f", &y); *xx = x; *yy = y; } 함수와 포인터 : 3~5pp 참조 • 인수로서 포인터 변수를 사용하면 복수 개의 자료를 호출 프로그램으로 반환할 수 있다. (Call by Address) • 실습예제 1 : 컴퓨터 개론과 C언어 및 실습 점수를 사용자 입력을 통해 출력하는 프로그램이다. main() 함수에서 두 과목의 점수를 저장할 변수를 선언하고 부함수에서 두 과목의 점수를 입력 받아 main()함수로 전달하여 점수를 출력하는 프로그램을 작성하시오.

  28. #include <stdio.h> double square(double x); void main() { double x; double (*squarep)(double); x=3.0; squarep= square; printf("x=%lf\n", square(x)); printf("x=%lf\n", (*squarep)(x)); printf("x=%lf\n", squarep(x)); } double square(double x) { return(x*x); } 3가지 함수호출 방법 1.square(x); /* 함수이름사용 */ 2. squarep= square; (*squarep)(x) ; /* 함수자체를 사용 */ 3. squarep =square; squarep(x); /* 함수포인터 이용 */ 함수에 대한 포인터 : 6~9pp 참조 • 함수 주소를 포인터 변수에 저장 • 보기 8-1 세가지 함수의 호출방법들은 모두 동등한 실행 결과를 얻는다. square(x) (*squarep)(x) squarep(x)

  29. 함수에 대한 포인터 : 6~9pp 참조 • 함수 주소를 포인터 변수에 저장 • 보기 8-1-1 세가지 함수의 호출방법들은 모두 동등한 실행 결과를 얻는다. #include <stdio.h> void square(double); void main() { double x; void (*squarep)(double); x=3.0; squarep= square; square(x); (*square)(x); squarep(x); } void square(double x) { printf("x=%lf\n", x*x); }

  30. 104 : : : 100 48 44 y x 100 a 104 b 1 200 3 p 204 q 함수에 대한 포인터 : 3~5pp 참조 • 예제 1 : 포인터가 함수의 인수로 사용되면 함수의 호출은 call by address가 된다. 함수의 실행시에 인수의 주소가 함수 호출로 넘어가기 때문에 함수 수행의 완료 후에도 변화된 값이 계속 유지되게 된다. #include <stdio.h> call_ref(int *x, int *y) { *x = 3; *y = 5; } void main() { int a, b; int *p, *q; a=1; b=3; p=&a; q=&b; printf("\n *p=%d, *q=%d", *p, *q); call_ref(p, q); printf("\n *p=%d, *q=%d\n", *p, *q); } 3 5 100 104

  31. : : : #include <stdio.h> void call_ref(float *x, float *y); void main() { float subj_1 = 4.0, subj_2 = 4.5; float *fp1, *fp2; fp1 = &subj_1; fp2 = &subj_2; printf("컴퓨터 개론의 점수는 %.1f점 입니다.\n", subj_1); printf("C언어및실습의 점수는 %.1f점 입니다.\n", subj_2); call_ref( fp1, fp2 ) ; printf("컴퓨터 개론의 백분율 점수는 %.0f점 입니다.\n", subj_1); printf("C언어및실습의 백분율 점수는 %.0f점 입니다.\n", subj_2); } void call_ref(float * x, float * y) { *x = (float)(*x / 4.5 * 100); *y = (float)(*y / 4.5 * 100); } 함수와 포인터 : 3~5pp 참조 • 인수로서 포인터 변수를 사용하면 복수 개의 자료를 호출 프로그램으로 반환할 수 있다. (Call by Address) • 실습예제 2 : 컴퓨터 개론과 C언어 및 실습 점수가 각각 4.0, 4.5이다. main() 함수에서 두 과목의 점수를 초기화하고 부함수를 통해 백분율 점수로 환산된 값을 변환하여 main()함수에서 점수를 출력하는 프로그램을 작성하시오. 1000 2000 x y 1000 2000 fp1 fp2 1000 2000 4.0 4.5 subj_1 subj-2

  32. 포인터의 배열 : 12~15pp 참조 • 포인터 배열의 특징 • 실습예제 3 : 포인터 배열을 사용하여 다음 단어들을 초기화하고 출력하시오. “Apple”, “Banana”, “Coconut”, “Melon”, “Papaya” #include <stdio.h> void main() { char *fruits[5]; inti; fruits[0]="[1] Apple"; fruits[1]="[2] Banana"; fruits[2]="[3] Coconut"; fruits[3]="[4] Melon"; fruits[4]="[5] Papaya"; for(i=0; i<5; i++) printf("%s\n", fruits[i]); }

  33. 포인터의 배열 : 12~15pp 참조 • 포인터 배열의 특징 • 예제 2 : 포인터 배열에 의한 메뉴의 출력 프로그램 #include <stdio.h> #include <string.h> #define MAXMENU 9 void main() { char *ps[MAXMENU+1]; inti, sum; ps[1]="[1] Load"; ps[2]="[2] Pick"; ps[3]="[3] New"; ps[4]="[4] Save"; ps[5]="[5] Write to"; ps[6]="[6] Directory"; ps[7]="[7] Change dir"; ps[8]="[8] OS shell"; ps[9]="[9] Quit"; for(i=1; i<=MAXMENU; i++) printf("%s\n", ps[i]); printf("\nSize of pointer array ps : %d bytes.\n\n", sizeof(ps)); for(sum=0, i=1; i<=MAXMENU; i++) sum+=strlen(ps[i])+1; printf("Total real length of all strings : %d bytes.\n\n", sum); printf("Total memory allocated : %d + %d = %d bytes.\n",sizeof(ps), sum, sizeof(ps)+sum); }

  34. 포인터의 포인터 : 12~15pp 참조, 연습 33pp 참조 • 포인터배열 예제 • 메뉴 선택 : 함수 포인터 사용 예 #include <stdio.h> #define MAXMENU 9 voidmain(){ char *ps[MAXMENU+1]; inti, sum; ps[1]="Load"; ps[2]="Pick"; ps[3]="New"; ps[4]="Save"; ps[5]="Write to"; ps[6]="Directory"; ps[7]="Change dir"; ps[8]="OS shell"; ps[9]="Quit"; for(i=1; i<=MAXMENU; i++) printf("[%d] %s\n",i, ps[i]); printf("********* Menu Number Input *********\n"); scanf("%d",&i); printf("you was choose \"%s\"\n",ps[i]); }

  35. 포인터의 포인터 • 포인터 배열 예제 #include <windows.h> #include <stdio.h> #include <conio.h> #include<time.h> #define MAX 3 const char *table[MAX] = {"-_ㅡ","-_-","ㅡ_-"}; void print(intnum){ system("cls"); printf("%s\n",table[num]); } void main() { intnum; char ch; srand(time(0)); while(1){ ch = getch(); if(ch != -1){ if(ch == 27) break; switch(ch){ case '1' : print(0); break; //table+0 case '2' : print(1); break; //table+1 case '3' : print(2); break; //table+2 default: print(rand()%MAX); break; } } } }

  36. 포인터의 배열 : 12~15pp 참조 • 포인터 배열의 특징 • 예제 3 : pps에 의한 포인터 배열 ps의 참조 프로그램 #include <stdio.h> void main() { char *ps[3], **pps; int j; pps=ps; pps[0]="Breakfast\n"; pps[1]="Lunch\n"; pps[2]="Supper\n"; for(j=0; j<3; j++) printf(pps[j]); }

  37. 포인터의 포인터 : 12~15pp 참조 이중 포인터의 개념 예제 4 : *(*week+n)과 **(week+n)의 이용 프로그램 번지 변수 52 4333612 week[2] 51 week[1] 4333616 50 week[0] 4333620 #include <stdio.h> void main() { static char *week[] = { "sun", "mon", "tue", "wed", "thu", "fri", "sat" }; int n; for(n=0; n<4; n++) printf("%c\n", *(*week+n)); for(n=0; n<4; n++) printf("%c\n", *(*week+n-4)); for(n=0; n<4; n++) printf("%c\n", *(*week+n-8)); for(n=0; n<4; n++) printf("%c\n", *(*week+n-12)); for(n=0; n<4; n++) printf("%c\n", *(*week+n-16)); for(n=0; n<4; n++) printf("%c\n", *(*week+n-20)); for(n=0; n<4; n++) printf("%c\n", *(*week+n-24)); for(n=0; n<7; n++) printf("%c %d\n", **(week+n), *(week+n)); } #include <stdio.h> void main() { static char *week[] = { "sun", "mon", "tue", "wed", "thu", "fri", "sat" }; int n; for(n=0; n<28; n++) printf("%c\n", *(*week+n)); for(n=0; n<7; n++) printf("%c\n", **(week+n)); } … 433623 \0 433622 n 433621 u 433620 s 433619 \0 433618 n 433617 o 433616 m 433615 … … 433599 \0 433598 t 433597 a 433596 s 37

  38. 포인터의 포인터 : 16~19pp 참조 • 이중 포인터의 개념 • 예제 4_1 : *(*week+n)과 **(week+n)의 이용 프로그램 #include <stdio.h> void main() { static char *week[] = { "SEOUL", "KOREA" }; int n; for(n=0; n<6; n++) printf("%c\n", *(*week+n)); for(n=0; n<6; n++) printf("%c\n", *(*week+n-8)); for(n=0; n<2; n++) { printf("%c ", **(week+n)); printf("%d\n", *(week+n)); } }

  39. : : : 포인터의 포인터 : 16~19pp 참조 • 이중 포인터의 개념 • 예제 5 : a=30, b=40을 사용자 정의 함수를 만들어서 연산(a+b)하고, 이 피호출 함수를 포인터 함수 이용하여 연산하는 프로그램 #include <stdio.h> inthap(int x, int y){ return(x+y); } void main() { int a, b, c; int hap(), (*func)(int, int); // 두개의 인수선언 a=30; b=40; printf("===== function only ======\n"); c=hap(a,b); printf("%d + %d = %d\n", a, b, c); printf("\n===== function pointer =====\n"); func=hap; c=(*func)(a,b); printf("%d + %d = %d\n", a, b, c); } 30 40 x y 1000 2000 30 40 a b

  40. 포인터의 포인터 : 16~19pp 참조 • 이중 포인터의 개념 • 예제 5-1 : 사용자에게 학점(4.5)을 입력받아 사용자 정의 함수를 만들어서 백분율 점수로 환산하고, 이 피호출 함수를 포인터 함수로 이용하는 프로그램 #include <stdio.h> float Cvt100(float x) { return((float)(x/4.5*100)); } void main() { float a,c; float Cvt100(), (*func)(float); printf("점수를 입력하세요 : "); scanf("%f",&a); printf("===== function only ======\n"); c=Cvt100(a); printf("%f\n", c); printf("\n===== function pointer =====\n"); func=Cvt100; c=(*func)(a); printf("%f\n", c); }

  41. 포인터의 포인터 • 함수포인터 예제 • 이벤트 처리 구현 #include <stdio.h> #include <conio.h> void onKeyEvent(int a); void keyEvent(void (*key)(int)); void main() { char ch; keyEvent(onKeyEvent); while(1){ ch = getch(); if(ch != -1){ keyEvent(NULL); } } } void onKeyEvent(int a) { printf("%d",a); } void keyEvent(void (*key)(int)){ static void (*evnt)(int); if( key != NULL){ evnt = key; evnt(1); }else if(key == NULL && evnt != NULL) evnt(1); }

  42. 실 습 • 실습문제 1 • 사용자에게 두수를 입력 받아 사칙연산을 하는 프로그램을 작성하라. 사칙연산에 대한 메뉴를 포인터 배열로 작성하고, 번호를 선택하여 사칙연산에 해당하는 부함수를 포인터 함수를 사용하여 호출 하시오 • 실행 결과

  43. : : : : 포인터의 사용(포인터변수, 포인터함수,포인터 배열) • 포인터변수 • 포인터함수 • 포인터배열( 가변길이문자열) mem[0] =1000 (주소) *mem[0] =“cup” (문자열) funp=1000 *funp = 함수 fun() 그 자체코드임 ptr =1000 *ptr=10 *funp *ptr *mem ptr 1000 : 1000 i 10 funp int *ptr; inti = 10; ptr = &i : printf(%d %d\n”, i, *ptr); . i의값과 *ptr의 값은 같음 . ptr의 값은 변수 i값(=10)이 저장된 주소로 1000번지임. . *ptr의 값은 1000번지 에 저장된 값 10임. 1000 3 main() { int x, = 3; int (*funp)(int); funp = fun; //함수명이 함수()의 시작주소를 나타냄fun(); // 또는 (*funp)(x); 또는 funp(x) } fun() { … } . funp의 값은 함수 fun() 이 저장되는 시작주소 1000임. . *funp의 값은 함수 fun() 그자체 코드임. • char *mem[3] = {“cup”, “apple”, “people”}; • 배열포인터 • . mem[0] = 1000, • . mem[1] = 1016, • . mem[2] =1040 •  배열포인터가 가리키는 값 • . *mem[0] = “cup”; // cup\0 • . *mem[1] = “apple” // applew0 • . *mem[2] = “people” //people\0 800 1000 mem[0] 996 mem[1] 1016 mem[2] 1040 fun() 1000 fun() { : : } x c 1000 1004 u 1008 p 1012 \0 1016 a 1040 : 함수호출 예 : fun(x) = *funp(x) = funp(x)

  44. 포인터의 사용(포인터 *, 포인터의 포인터 ** ..) 김철수의 위치(주소)? 홍길동에게 김철수위치를알려야함 ppa = &pa 케익의 위치(주소)? 김철수에게 알려야함 pa = &a 김철수 pa “케익” 케익의 위치 a=3 &a 홍길동 ppa 포인터변수 이용 * pa ? 포인터의포인터변수 이용 ** ppa ? 변수 a ? a에 저장된 값이 3이다 *pa 도 3이다 **ppa도 3이다

More Related