1 / 47

Chapter8. 포인터

Chapter8. 포인터. 포인터의 기본 인자 전달 방법 포인터와 배열 포인터와 문자열. 변수의 주소를 저장하는 포인터에 대해 알아본다 . 함수의 인자를 값과 주소로 전달하는 방법을 알아본다 . 포인터와 배열의 관계를 알아본다 . 포인터와 문자열의 관계를 알아본다. 1. 포인터의 기본. 포인터 (Pointer) 일반변수의 메모리 내 주소번지를 저장함 메모리의 위치를 가리킨다는 (point) 의미에서 포인터 (pointer) 라고 부름 . C 언어의 가장 대표적인 특징 중 하나

Download Presentation

Chapter8. 포인터

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. Chapter8.포인터

  2. 포인터의 기본 인자 전달 방법 포인터와 배열 포인터와 문자열

  3. 변수의 주소를 저장하는 포인터에 대해 알아본다. 함수의 인자를 값과 주소로 전달하는 방법을 알아본다. 포인터와 배열의 관계를 알아본다. 포인터와 문자열의 관계를 알아본다.

  4. 1. 포인터의 기본 • 포인터(Pointer) • 일반변수의 메모리 내 주소번지를 저장함 • 메모리의 위치를 가리킨다는(point) 의미에서 포인터(pointer)라고 부름. • C 언어의 가장 대표적인 특징 중 하나 • 사용하고자 하는 대상에 변수명을 통하지 않고, 직접 접근 가능 • 프로그래밍할 때 간결하고 효율적인 제어 가능

  5. 1.1 포인터 선언 • 포인터 선언하는 방법 • * 연산자가 하나면 1차원 포인터 • 1차원 포인터는 일반변수의 주소를 값으로 가짐 • 선언 예 • 일반변수 i의 주소 :& 연산자를 이용해 &i로 표현 • 변수 ptr:1차원 포인터, 일반 변수의 주소를 값으로 가짐 • int* 는 변수 ptr에 정수형으로 선언된 변수의 주소가 들어올 수 있음을 의미함

  6. 1.1 포인터 선언 • 포인트 변수의 크기 • 포인터 변수 ptr 자체의 크기는 4바이트 • char*로 선언되든 double*로 선언되든 관계없음. • *의 위치 • 포인터 변수 선언에서 *는 선언하려는 자료형과 포인터 변수명 사이에만 위치하면 됨 어느 쪽에 가깝든 상관없음. 모두 4바이트

  7. 1.2 포인터를 이용한 일반 변수로의 접근 • 포인터는 일반 변수의 주소와 같음 • ptr은 변수 a의 주소인 &a와 같음 • 포인터를 통해 일반 변수의 값으로 접근함 • 포인터로 선언한 변수에 * 연산자를 붙이면, 포인터가 가리키는 주소에 저장된 값을 의미함

  8. 1.2 포인터를 이용한 일반 변수로의 접근 • 예제 10-1) 포인터 기본 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 #include <stdio.h> int main(void) { inti = 10; int *ptr = &i; printf("ptr의 주소값 : %p\n", &ptr); printf("i의 주소값 : %p\n", &i); printf("i의 주소값 : %p\n\n", ptr); printf("i의 값 : %d\n", i); printf("i의 값 : %d\n", *ptr); return 0; }

  9. 1.2 포인터를 이용한 일반 변수로의 접근 • 포인터를 이용한 연산

  10. 1.2 포인터를 이용한 일반 변수로의 접근 • 예제 10-2) 포인터를 통한 연산 기본예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 #include <stdio.h> int main(void) { inti = 10; int *ptr = &i; *ptr = i + 20; printf("i값 : %d \n", i); i = i + 20; printf("i값 : %d \n", *ptr); return 0; }

  11. 1.2 포인터를 이용한 일반 변수로의 접근 • 혼자해보기10-1) 다음 프로그램의 실행결과를 예측하시오. (단, a의 주소 번지를 1000번, p의 주소 번지를 1200번이라고 가정한다) 01 02 03 04 05 06 07 08 09 10 11 12 13 14 #include <stdio.h> int main(void) { int a = 10; int* p = &a; printf("%p ", p); printf("%p ", &p); printf("%d ", *p); return 0; return 0; }

  12. 1.3 포인터의 유용성 • 예제 10-3) 포인터를 사용하지 않고 두 수를 바꾸는 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <stdio.h> void Swap(int a, int b); int main(void) { int x = 10, y = 5; printf("Swap() 함수 실행 전\n"); printf("x = %d, y = %d이다.\n\n ", x, y); Swap(x, y); printf("Swap() 함수 실행 후\n"); printf("x = %d, y = %d이다.\n", x, y); return 0; } void Swap(int a, int b) { int temp; temp = a; a = b; b = temp; }

  13. 1.3 포인터의 유용성 • 포인터를 사용하지 않고 두 수를 바꾸는 프로그램 • main( ) 함수에서 Swap( ) 함수를 호출할 때, • 인자로 전달된 변수 x, y는 x, y 자체가 아니라 값 • 변수 x, y는 main( ) 함수에서 선언한 지역 변수기 때문에 메모리에 생존해있음

  14. 1.3 포인터의 유용성 • 포인터를 사용해 두 수를 바꾸는 프로그램 • 포인터를 함수의 인자로 사용하면 주소값을 전달할 수 있으므로 변수 자체가 함수에 전달됨. 따라서 함수를 통해 두 수의 값을 바꿀 수 있음.

  15. 1.3 포인터의 유용성 • 예제 10-4) 포인터를 사용하여 두 수를 바꾸는 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <stdio.h> void Swap(int* a, int* b); int main(void) { int x = 10, y = 5; printf("Swap() 함수 실행 전\n"); printf("x = %d, y = %d이다.\n\n", x, y); Swap(&x, &y); printf("Swap() 함수 실행 후\n"); printf("x = %d, y = %d이다.\n", x, y); return 0; } void Swap(int* a, int* b) { int temp; temp = *a; *a = *b; *b = temp; }

  16. 2.1 인자를 값으로 전달 • 인자(매개변수)의 전달 방법 : 함수에 사용될 데이터를 보내는 방법 • 데이터의 값을 복사해서 보내는 방법/데이터의 주소를 전달하는 방법으로 나뉨 • 인자를 값으로 전달(Call by value) • 데이터의 값을 복사해함수에 전달 • 포인터를 사용하지 않고 작성했던 함수가 여기에 해당함 • C 언어의 대표적인 인자 전달 방식 • 함수가 호출되면 인자값을스택(Stack)이라는 기억장소에 복사 • 값을 복사하기 때문에 호출된 함수에서 인자값을 바꾸더라도 main( ) 함수는 전혀 영향을 받지 않으므로 두 함수는 독립적이며 안전함

  17. 2.2 인자를 주소로 전달 • 인자를 주소로 전달(Call by reference) • 전달하려는 변수의 주소를 함수에 전달 • 함수에 변수 자체를 전달해야 할 때 사용함 • C언어에서는 포인터를 이용 • 변수의 주소값을 주소 연산자(&)를 이용해 함수에 넘겨줌 • 주소값을 받는 함수에서는 간접 연산자(*)를 이용해 이 주소값이 가리키는 값을 읽거나 저장

  18. 2.2 인자를 주소로 전달 • 예제 10-5) 인자 전달 방법 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <stdio.h> void CountIncrement1(int n); // 값을 전달 void CountIncrement2(int* n); // 주소를 전달 int main(void) { int a = 10; printf("a의 초깃값 : %d\n", a); CountIncrement1(a); printf("CountIncrement1 함수 실행 후 a의 값 : %d\n", a); CountIncrement2(&a); printf("CountIncrement2 함수 실행 후 a의 값 : %d\n", a); return 0; } void CountIncrement1(int n) { n++; } void CountIncrement2(int* n) { (*n)++; }

  19. 3.1 포인터와 배열의 관계 • 배열명 • 그 자체로 해당 데이터가 있는 시작 주소를 의미하는 포인터 상수 • 상수기 때문에, 배열명에 증감 연산자(++, --) 등을 이용해 배열명의 값을 바꿀 수 없음 • 배열 원소의 주소에 접근하는 방법 • 배열명 • 포인터 • 배열을 이용해 포인터를 초기화하는 방법

  20. 3.1 포인터와 배열의 관계 • 배열과 포인터간 대응 관계 배열 첨자 배열명 포인터

  21. 3.1 포인터와 배열의 관계 • 배열 a의 주소를 표현하는 방법 • 배열명 a는 배열의 시작 주소를, a + 1은 배열 a의 두 번째 주소를 나타냄 • 여기서 1은 산술적인 의미의 숫자 1이 아니라 그 다음 주소를 의미함 • 포인터 변수 p도 같은 방법으로 배열의 주소를 표시 가능함 배열 첨자 배열명 포인터

  22. 3.1 포인터와 배열의 관계 • 배열 a의 값을 표현하는 방법 • 간접 연산자 *는 주소에 들어있는 값을 의미 • 배열명a: 배열의 시작 주소 • *a: 배열의 시작 주소에 들어있는 값. 따라서 *a와 a[0]는 같은 의미. • 포인터를 이용해 값을 표현할 때 주의할 점 배열 첨자 배열명 포인터 포인터

  23. 3.1 포인터와 배열의 관계 • 예제 10-6) 배열과 포인터의 관계 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <stdio.h> int main(void) { int a[] = {10, 20, 30, 40, 50}; int *p = a; inti; printf("배열명a를 이용한 주소 표현\n"); for(i = 0; i < 5; i++) printf("a[%d]의 주소 %p\n", i, a + i); printf("\n포인터 p를 이용한 배열 주소 표현\n"); for(i = 0; i < 5; i++) printf("a[%d]의 주소 %p\n", i, p + i); printf("\n포인터 p를 이용한 배열값 표현\n"); for(i = 0; i < 5; i++) printf("a[%d] = %d\n", i, *(p + i)); return 0; }

  24. 3.1 포인터와 배열의 관계 • 혼자해보기10-2) 다음 프로그램의 실행 결과를 예측하시오. 01 02 03 04 05 06 07 08 09 10 11 12 13 #include <stdio.h> int main(void) { int a[] = {5, 10, 15, 20, 25}; int * p = a; inti; for(i = 0; i < 5; i++) printf("*(p+%d) + %d = %d이다.\n", i, i, *(p+i) +i); return 0; }

  25. 3.2 증감 연산자 적용 • 포인터에서 증감 연산자 • p++: 포인터 p가 가리키는 곳의 다음 주소 • *p++: 포인터 p가 가리키는 곳의 다음 주소 안에 들어있는 값 • 배열명에서 증감 연산자 : 사용할 수 없음 • a++: 배열명a는 상수이므로 상수에 증감 연산자를 사용할 수 없음 • 3++처럼 상수에 증감 연산자를 사용하는것과 같음

  26. 3.2 증감 연산자 적용 • 예제 10-7) 포인터 변수와 증감연산자 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 #include <stdio.h> int main(void) { int a[] = {11, 22, 33, 44, 55}; int *p = a; printf("*p의 값 = %d\n", *p); p++; printf("*(p+1)의 값 = %d\n", *p); p++; printf("*(p+2)의 값 = %d\n", *p); p--; printf("*(p+1)의 값 = %d\n", *p); return 0; }

  27. 3.2 증감 연산자 적용 • 배열의 합을 구하는 함수를 만든 예 함수의 인자로 배열 사용 메모리 이동량이 많아짐

  28. 3.2 증감 연산자 적용 • 포인터를 이용한 배열의 합을 구하는 함수 함수의 인자로 포인터 사용 4바이트만 메모리로 이동

  29. 3.2 증감 연산자 적용 • 예제 10-8) 포인터를 이용해 배열을 함수 인자로 전달하는 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <stdio.h> intSumArray(int* pA, int Size); int main(void) { int a[ ] = {10, 5, 15, 25, 7}; int Sum; Sum = SumArray(a, 5); //함수의 호출 printf("배열의 합 : %d \n", Sum); return 0; } intSumArray(int* pA, int Size) { int result = 0, i; for(i = 0; i < Size; i++) result += pA[i]; // result += *(pA + i); // result += *pA++; return result; }

  30. 3.2 증감 연산자 적용 • 포인터로 계산식을 표현하는 방법 • pA[i] = *(pA +i) = *pA++ • *pA++는 * 보다 ++ 연산자가 우선순위가 빠르므로 배열의 원소값을 나타낼 수 있음 • *pA++/(*pA)++ • 서로 의미가 다름 • 두 번째 표현은 pA가 가리키는 곳의 값을 연산 후에 1만큼 증가시키라는 의미 • [예제 10-7]의 for문을 아래와 같이 작성하면 원하는 결과가 나오지 않음

  31. 3.2 증감 연산자 적용 • 혼자해보기10-3) [예제 10-8]에서 함수의 정의 부분을 다음과 같이 수정한 후 실행해보시오. 01 02 03 04 05 06 07 intSumArray(int* pA, int Size) { int result = 0, i; for(i = 0; i < Size; i++) result += (*pA)++; return result; };

  32. 4.1 포인터를 이용한 문자열 표현 • 포인터를 이용한 문자열 선언 방법과 사용 예 문자열의 마지막을 나타내는 NULL

  33. 4.1 포인터를 이용한 문자열 표현 • 예제 10-9) 포인터를 이용해서 문자열을 출력하는 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 #include <stdio.h> int main(void) { char *pC = "C programming"; printf("문자열을 변환기호를 이용해서 출력\n"); printf("%s\n", pC); printf("반복문을 이용해 한 글자씩 출력\n"); while(*pC) printf("%c", *pC++); printf("\n"); return 0; }

  34. 4.1 포인터를 이용한 문자열 표현 • 배열 포인터 • 문자열을 동시에 여러 개 만들어야 할 경우 유용함 • 포인터 배열을 나타낸 예로 배열 원소인 pStr[0], pStr[1], pStr[2] 모두 문자열 포인터고 [그림10-6]과 같이 각 문자열의 시작 주소를 가리킴

  35. 4.1 포인터를 이용한 문자열 표현 • 배열포인터 - 크기 • 배열의 크기를 초기에 지정하지 않아도 됨 • 포인터 배열을 이용하면 불필요한 메모리의 낭비를 막을 수 있음 • 배열 포인터를 이용하지 않는다면?! (2차원 배열로 문자열 선언) • 2차원 배열을 이용해서 문자열을 동시에 선언하면, 문자가 가장 많은 문자열이 기준이 되기 때문에 [그림 10-7]과 같이 메모리의 낭비가 발생

  36. 4.1 포인터를 이용한 문자열 표현 • 예제 10-10) 포인터 배열을 이용한 문자열 출력 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 #include <stdio.h> int main(void) { char *pStr[] = {"english", "math", "korean"}; char subject[][8] = {"english", "math", "korean"}; inti; printf("포인터 배열을 이용해서 문자열을 출력합니다.\n"); for(i = 0; i < 3; i++) printf("pStr[%d] = %s\n", i, pStr[i]); printf("이차원 배열을 이용해서 문자열을 출력합니다.\n"); for(i = 0; i < 3; i++) printf("subject[%d] = %s\n", i, subject[i]); return 0; }

  37. 4.1 포인터를 이용한 문자열 표현 • 예제 10-10) 포인터 배열을 이용한 문자열 출력 예제

  38. 4.2 문자 처리 함수 • 예제 10-11) 소문자를 대문자로 바꾸는 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 #include <stdio.h> int main(void) { char *pC = "c language"; while (*pC) { printf("%c", *pC-32); pC++; } printf("\n"); return 0; }

  39. 4.2 문자 처리 함수 • 문자 처리 함수 • 문자와 관련된 기능을 수행하는 일련의 함수 • Ex) 문자를 변환하거나 원하는 값으로 바꿈 • <ctype.h>에 정의됨

  40. 4.2 문자 처리 함수 • 예제 10-12) 문자 처리 함수를 이용한 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 #include <stdio.h> #include <ctype.h> int main(void) { char *pC = "c language"; while(*pC) { printf("%c", toupper(*pC++)); } printf("\n"); return 0; }

  41. 4.3 문자열 처리 함수 • 예제 10-13) 문자열의 크기를 알아내는 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 #include <stdio.h> intstrleng(char *ch); int main(void) { intlen; char str[ ] = "c language and data structure"; len = strleng(str); printf("문자열의 크기는 %d다.\n", len); return 0; } intstrleng(char *ch) { int index; for(index = 0; *(ch+index) != '\0'; index++); return index; }

  42. 4.3 문자열 처리 함수 • 문자열을 처리하는 함수 • size_tstrlen(const char*) 함수: NULL을 제외한 문자열의 크기 반환 • 사용 예 • 결과

  43. 4.3 문자열 처리 함수 • int strcmp(const char* s1, const char* s2) 함수: 두 문자열 비교 • 사용 예 • 결과

  44. 4.3 문자열 처리 함수 • char* strcpy(char* s1, const char* s2) 함수 : 첫 번째 문자열에 두 번째 문자열 복사 • 사용 예 • 결과

  45. 4.3 문자열 처리 함수 • char* strcat(char* s1, const char* s2)함수 : 첫 번째 문자열에 두 번째 문자열 연결 • 사용 예 • 결과

  46. 4.3 문자열 처리 함수 • 예제 10-14) 문자열 처리 함수 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <stdio.h> #include <string.h> int main(void) { char cmp1[40] = "C programming"; char cmp2[ ] = "Java programming"; char cmp3[ ] = "C programming"; char str[ ] = " is easy"; int length, i; length = strlen(cmp1); for(i = 0; i < length; i++) printf("%c", cmp1[i]); printf("\n"); printf("cmp1과 cmp2는 서로 %s\n", strcmp(cmp1, cmp2) ? "같지 않다." : "같다."); printf("cmp1과 cmp3는 서로 %s\n", strcmp(cmp1, cmp3) ? "같지 않다." : "같다."); printf("cmp1에 cmp2를 복사하면\"%s\"이 출력된다.\n", strcpy(cmp1, cmp2)); printf("cmp1에 str를 연결하면\"%s\"가 출력된다.\n", strcat(cmp1, str)); return 0; }

More Related