Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

포인터의기초 (2) - 포인터 사용하기1

포인터의기초 (2) - 포인터 사용하기1

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to comment

포인터의기초 (2) - 포인터 사용하기1

  1. 1. C언어와 포인터 (1) 포인터의 사용법 "완전학습을 지향하는" NHN NEXT 정호영 나눔고딕 및 나눔고딕코딩 글꼴을 설치해 주세요.
  2. 2. 포인터의 용도 1. 원하는 메모리 번지에 직접 값을 쓰기 2. 변수의 동적 할당 3. Call by Reference 4. 배열과 문자열의 조작 5. 구조체의 효율적 사용 등등…
  3. 3. 0. void 포인터 이야기
  4. 4. void *는 무엇이든 담을 수 있는 그릇입니다. void *ptr; int a = 10; double d = 3.14; ptr = &a; //ok ptr = &d; //ok
  5. 5. void 포인터에 * 연산자를 사용하면 어떻게 될까요? void *ptr; double d = 3.14; ptr = &d; //ok printf("%fn", *ptr);
  6. 6. void 포인터는 포인티의 타입이 정해지지 않았기 때문에 읽을 수 없습니다. 그럼 어떻게 void 포인터의 포인티 값을 읽을까요?
  7. 7. 정답은 캐스팅 (형변환) 입니다. 1. void 포인터를 포인티의 포인터 타입으로 형변환 2. * 연산자를 붙여서 값을 읽는다. 예제 (double *) ptr void *ptr; double d = 3.14; ptr = &d; //ok printf("%fn", *((double *)ptr)); //ok *((double *) ptr)
  8. 8. 불편한 void*를 왜 사용하는지는 조금 뒤에…
  9. 9. 1. 메모리에 직접 값을 쓰기
  10. 10. 메모리의 원하는 번지에 직접 값을 쓰는 경우가 있습니다. 하드웨어를 직접 제어하는 경우, 많이 사용합니다. 예) 0x378 번지의 값이 1이면 USB가 살아있다. char *alive = (char *) 0x378; if (*alive == 1) { //USB가 살아 있구나. 뭘 하지? } else { //USB가 안 살아있음, 다른 일을 하자. }
  11. 11. 2. 동적할당 malloc calloc free
  12. 12. 지난 시간에 우리 마음대로 사용할 수 있는 heap 이라고 하는 공간이 있다고 했습니다. 이 공간을 배정받는 함수 malloc() calloc() 반납하는 함수 free()
  13. 13. void *malloc(size_t size); void free(void *ptr); void *calloc(size_t n, size_t size); 우리가 요청한 크기만큼 힙에 공간을 할당해 줍니다. 리턴값은 요청한 공간의 시작주소입니다. free함수는 할당한 메모리를 해제할 때 사용합니다. 할당하고 해제하지 않으면 leak이 발생할 수 있습니다.
  14. 14. 예제) int 크기만큼 공간을 할당받고 싶어요. //NAVER cast void * to int * in this case! int *ptr = malloc(sizeof(int)); *ptr = 50; printf("%dn", *ptr); free(ptr);
  15. 15. 예제) int 3개만큼 동적 할당을 하고 싶어요. *포인터의 덧셈이 잠깐 나왔습니다. int *ptr = malloc(sizeof(int)*3); int *temp; *ptr = 10; temp = ptr + 1; *temp = 20; printf("%dn", *ptr); //10 printf("%dn", *(ptr + 1)); //?
  16. 16. 예제) calloc을 사용해 봅시다. *포인터의 덧셈이 잠깐 나왔습니다. int *ptr = calloc(3, sizeof(int)); int *temp; *ptr = 10; temp = ptr + 1; *temp = 20; printf("%dn", *ptr); printf("%dn", *(ptr + 1));
  17. 17. 3. Call by Reference
  18. 18. C언어의 먼 선조인 포트란은 함수에 인자를 전달할 때 원본을 그대로 전달했습니다. 아래 언어가 포트란이라면… void foo(int i) { i = i + 10; } main() { a = 100; foo(a); printf("%dn", a); } // 포트란이라면 (오해하지 마세요) // 200 // C니까 100
  19. 19. 조금 더 자세한 설명을 위해 용어를 정의합니다. argument: 실제 호출하는 쪽에서는 넘겨주는 변수 parameter: 함수의 정의에 있는 변수 앞쪽에서 parameter: i argument: a 모르는 분이 엄청 많습니다.
  20. 20. 중요한 건 C언어는 argument 에서 parameter 로 갈 때 복사본을 전달해 준 다는 사실입니다. 이것을 call by value 라고 합니다. -- return 값도 마찬가지로 복사가 일어납니다.
  21. 21. call by value - argument의 값이 바뀌지 않는다. - 복사본을 전달한다. call by reference - argument의 값이 바뀐다. - 원본을 전달한다. call by value는 성능상 문제가 되기도 합니다.
  22. 22. 그런데 C 언어에는 call by reference 가 없습니다!! 뭐라고??
  23. 23. Java - 일반 변수는 call by value - 배열, 클래스 등 복합 타입 변수는 call by reference - 포인터는 완전히 사라졌다!
  24. 24. c++ - 선언에 &를 사용하면 참조 연산자! - c++ 최대의 실수 - 포인터도 여전히 사용할 수 있다. 프로그래머의 욕심은 끝이 없고, 같은 실수를 반복한다.
  25. 25. c# = C++ + C++ 기본 골격은 java와 같지만 내 마음대로 선언도 가능 parameter에 ref 키워드 사용하면 call by reference argument에도 반드시 ref 키워드를 사용해야 함
  26. 26. C언어에는 call by reference 흉내가 있습니다. call by address 라고 하는 게 더 맞는 표현입니다. 이 때 포인터를 사용합니다!
  27. 27. void foo(int *i) { *i = *i + 10; } int main(void) { int a = 100; foo(&a); printf("%dn", a); return 0; } //실행 결과 200
  28. 28. int 변수에 대해 call by reference 를 하기 위해서 int * 를 사용했습니다. char 변수의 call by reference를 하려면? double 변수의 call by reference를 하려면? int* 변수의 call by reference를 하려면?
  29. 29. int 변수에 대해 call by reference 를 하기 위해서 int * 를 사용했습니다. char 변수의 call by reference를 하려면? char * double 변수의 call by referenc를 하려면? double * int* 변수의 call by reference를 하려면? int **
  30. 30. int myalloc(int *ptr, unsigned int size)를 구현합니다. - int 전용 동적할당 함수 - 성공하면 size, 실패하면 -1을 리턴 int myalloc (int *ptr, unsigned int numb) { //implement } int main(void) { int *ptr = NULL; int ret = myalloc(ptr, 1); if (ret == -1) return 1; *ptr = 5054; printf("%dn", *ptr); return 0; }
  31. 31. 어떻게 구현하든지 앞의 함수는 틀렸습니다. argument로 전달한 ptr은 값이 바뀌지 않기 때문입니다. int *를 call by reference로 호출하려면 int **를 사용합니다. int myalloc (int **ptr, unsigned int numb) { *ptr = malloc(sizeof(int) * numb); if (ptr) return numb; else return -1; } int main(void) { int *ptr = NULL; int ret = myalloc(&ptr, 1); if (ret == -1) return 1; *ptr = 5054; printf("%dn", *ptr); return 0; }
  32. 32. 이중 포인터의 용법1 단일 포인터의 call by reference를 위해
  33. 33. 4. 포인터와 배열
  34. 34. C언어의 배열은 90% 정도 포인터랑 닮았습니다. 포인터에도 배열 연산을 그대로 쓸 수 있습니다! int arr[5]; double b[]= {1, 2, 3, 4, 5}; //자동으로 5개가 됨
  35. 35. 이 코드를 실행해 보고 알아낸 사실을 토의해 봅시다. int main(void){ int a[5] = {1,2,3,4,5}; printf("%pn", a); printf("%p %dn", &a[0], a[0]); printf("%p %dn", &a[1], a[1]); return 0; }
  36. 36. 놀랍게도 배열이름 변수에는 배열의 첫번째 원소의 주소가 들어갑니다! arr = &arr[0] int의 주소를 저장한 변수 = int * 포인터를 배열에 대입해서 쓸 수 있을까요?
  37. 37. HULL? int main(void){ int a[5] = {1,2,3,4,5}; int *ptr = a; //not &a, &a[0]도 OK printf("%pn", ptr); printf("%p %dn", ptr, *ptr); printf("%p %dn", ptr + 1, *(ptr +1)); return 0; }
  38. 38. HULL? 무언가 수상하지요? int main(void){ int a[5] = {1,2,3,4,5}; int *ptr = a; //not &a, &a[0]도 OK printf("%pn", ptr); printf("%p %dn", ptr + 0, *(ptr + 0)); printf("%p %dn", ptr + 1, *(ptr + 1)); return 0; } int main(void){ int a[5] = {1,2,3,4,5}; printf("%pn", a); printf("%p %dn", &a[0], a[0]); printf("%p %dn", &a[1], a[1]); return 0; }
  39. 39. HULL? 포인터가 미쳐 날뛰고 있습니다!! int main(void) { int a[5] = {1,2,3,4,5}; int *ptr = a; printf("%pn", ptr); printf("%p %dn", &ptr[0], ptr[0]); printf("%p %dn", &ptr[1], ptr[1]); return 0; } int main(void) { int a[5] = {1,2,3,4,5}; printf("%pn", a); printf("%p %dn", &a[0], a[0]); printf("%p %dn", &a[1], a[1]); return 0; }
  40. 40. 사실 a[i] 는 *(a + i) 랑 완전히 똑같습니다. 사람의 편의를 위해 읽기 쉽게 만들어 준 거랍니다. 이런 걸 syntax sugar 라고 합니다. a[i] = *(a + i) *나중에 다시 나오지만 a->b도 syntax sugar 입니다.
  41. 41. 다 아는 산수 한 번 해볼까요? a[3] = *(a + 3) = *(3 + a) = 3[a]
  42. 42. int main() { int a[5] = {1,2,3,4,5}; for (int i = 0; i < 5; i++) printf("%dn", i[a]); return 0; } (형~오빠~, 이거 어디가 잘못된 건지 좀 가르쳐 주세요.) 잘못된 건 비뚤어진 너의 마음이다 ㅋㅋ. 죄송합니다. 된다고 절대 사용하면 안 됩니다.
  43. 43. To be continued…

    Be the first to comment

    Login to see the comments

  • happyhooni

    Dec. 17, 2014

포인터의기초 (2) - 포인터 사용하기1

Views

Total views

1,718

On Slideshare

0

From embeds

0

Number of embeds

520

Actions

Downloads

26

Shares

0

Comments

0

Likes

1

×