Successfully reported this slideshow.
Your SlideShare is downloading. ×

포인터의 기초(1)

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 51 Ad

More Related Content

Viewers also liked (20)

Advertisement
Advertisement

Recently uploaded (20)

포인터의 기초(1)

  1. 1. C언어와 포인터 (1) 포인터의 기초 "완전학습을 지향하는" NHN NEXT 정호영 나눔고딕 및 나눔고딕코딩 글꼴을 설치해 주세요.
  2. 2. 쉽 게 씌 어 진 시 창 밖 에 밤 비 가 속 살 거 려 육 첩 방 은 남 의 나 라 . 시 인 이 란 슬 픈 천 명 인 줄 알 면 서 도 한 줄 시 를 적 어 볼 까 . 땀 내 와 사 랑 내 포 근 히 품 긴 보 내 주 신 학 비 봉 투 를 받 아 대 학 노 ― 트 를 끼 고 늙 은 교 수 의 강 의 들 으 러 간 다 . 생 각 해 보 면 어 린 때 동 무 를 하 나 , 둘 , 죄 다 잃 어 버 리 고 나 는 무 얼 바 라 나 는 다 만 , 홀 로 침 전 하 는 것 일 까 ? 인 생 은 살 기 어 렵 다 는 데 시 가 이 렇 게 쉽 게 씌 어 지 는 것 은 부 끄 러 운 일 이 다 . 육 첩 방 은 남 의 나 라 창 밖 에 밤 비 가 속 살 거 리 는 데 등 불 을 밝 혀 어 둠 을 조 금 내 몰 고 시 대 처 럼 올 아 침 을 기 다 리 는 최 후 의 나 . 나 는 나 에 게 적 은 손 을 내 밀 어 눈 물 과 위 안 으 로 잡 는 최 초 의 악 수 .
  3. 3. 쉽게 씌어진 C 창밖에 밤비가 속살거려 육첩방은 남의 나라. C인이란 슬픈 천명인 줄 알면서도 한 줄 C를 적어볼까. 땀내와 사랑내 포근히 품긴 보내주신 학비 봉투를 받아 대학 노―트를 끼고 늙은 교수의 강의 들으러 간다. 생각해보면 어린 때 동무를 하나, 둘, 죄다 잃어버리고 나는 무얼 바라 나는 다만, 홀로 침전하는 것일까? 인생은 살기 어렵다는데 C가 이렇게 쉽게 씌어지는 것은 부끄러운 일이다. 육첩방은 남의 나라 창밖에 밤비가 속살거리는데 등불을 밝혀 어둠을 조금 내몰고 C대처럼 올 아침을 기다리는 최후의 나. 나는 나에게 적은 손을 내밀어 눈물과 위안으로 잡는 최초의 악수.
  4. 4. 많은 초보들이 독학으로 C언어를 배우는 과정 1. C언어 책을 삽니다. 2. 책을 펼치고 열심히 공부합니다. 3. 포인터가 나옵니다. 4. 책을 덮습니다. 5. n개월 휴식 6. 1번 또는 2번으로 갑니다.
  5. 5. 이 슬라이드 목표는 여러분이 포인터에 대한 작은 깨달음을 얻는 것입니다. 그리고 진실과 다른 내용이 더러 나옵니다.
  6. 6. 기초 지식
  7. 7. 비트와 바이트 비트: 1또는 0을 저장할 수 있는 공간 바이트: 1비트 8개의 집합 0000 0000 ~ 1111 1111
  8. 8. 예제1) 1바이트로 표시할 수 있는 범위를 10진수로 나타내면? 예제2) 1바이트로 표시할 수 있는 범위를 16진수로 나타내면?
  9. 9. 예제1) 1바이트로 표시할 수 있는 범위를 10진수로 나타내면? 0 ~ 255 ( -128 ~ 127도 정답) 예제2) 1바이트로 표시할 수 있는 범위를 16진수로 나타내면? 00 ~ FF
  10. 10. 예제3) 다음 16진수 덧셈을 해 봅시다. 0 + 4 = 4 + 4 = 8 + 4 = C + 4 = C4 + 1C =
  11. 11. 예제3) 다음 16진수 덧셈을 해 봅시다. 0 + 4 = 4 4 + 4 = 8 8 + 4 = C C + 4 = 10 C4 + 1C = E0 16진수 0x4, 0x8, 0xC, 0x10은 각각 4, 8, 12, 16에 해 당되는 숫자입니다. 자주 나오니 기억합시다.
  12. 12. 잠깐 메모리에 대해 알아보고, &연산자도 알아 봅시다_
  13. 13. 메모리 컴퓨터의 메모리는 연속적인 선형 저장공간입니다. 각 바이트마다 고유한 주소를 가집니다. (32비트 PC에서) 가장 앞 주소: 0000 0000 가장 뒤 주소: FFFF FFFF ... 0000 0000 FFFF FFFF 0000 0001 FFFF FFFD
  14. 14. OS는 메모리의 일정한 주소를 묶어 영역으로 만들었습니 다. 각 영역마다 정해진 역할이 있습니다. 어떤 게임에서 그린벨트, 거주 구역, 공업지구 등으로 나눈 거랑 비슷합니다. 중3 성적을 말아먹은 게임
  15. 15. 메모리 영역은 크게 코드, 데이터, 스택, 힙으로 나뉩니다. 각각의 역할은 조금 나중에… 물론 이 그림은 추상화입니다.
  16. 16. 예제3) 메모리 주소를 표현하기 위해서 필요한 최소한의 크기는? ... 0000 0000 FFFF FFFF 0000 0001 FFFF FFFD
  17. 17. 예제3) 메모리 주소를 표현하기 위해서 필요한 최소한의 크기는? 4바이트 # unsigned int = 4바이트이므로 주소를 저장할 수 있다. ... 0000 0000 FFFF FFFF 0000 0001 FFFF FFFD
  18. 18. *참고 옛날 16비트 IBM DOS 시절에 int는 2byte(16bit)지만 메모리 주소는 20bit여서 unsigned int로 주소를 표현할 수 없었습니다. ... 0 0000 3 FFFF 0 0001 3 FFFD
  19. 19. 변수 1. 메모리의 어딘가에 필요한 크기만큼 자리를 잡고 2. 이름을 붙여줌 3. 적절한 값을 넣을 수 있음 int n = 10; //4바이트 char a = 'x'; //1바이트 double d = 5.23; //8바이트
  20. 20. 예제4) 다음 문장을 보고 찍어 보세요. 1. 위 문장에 필요한 공간은? 2. 위 변수의 이름은? 3. 위 변수의 타입은? double doo[] = { 3.14, 1.414, 1.717 };
  21. 21. 예제4) 다음 문장을 보고 찍어 보세요. 1. 위 문장에 필요한 공간은? 24바이트 2. 위 변수의 이름은? doo 3. 위 변수의 타입은? 더블의 배열 타입(?) double doo[] = { 3.14, 1.414, 1.717 };
  22. 22. 변수의 종류 전역 변수(global variable) 정적 변수(static variable) 지역 변수(local variable) = 자동변수(auto variable)
  23. 23. 단항 연산자 & 단항 연산자 (unary operator) &는 주소 연산자입니다. 변수의 주소를 알고 싶을 때 사용합니다. printf에서 주소를 출력할 때는 %p입니다.
  24. 24. 변수의 주소 알아보기 전역변수의 주소 지역변수의 주소 정적변수의 주소 포인터? 함수? 결과주소를 내림차순으로 정렬해 봅시다.
  25. 25. 변수가 위치하는 영역의 이름 종류 위치 설명 함수 코드 소스코드, 리터럴이 위치 전역 및 정적변수 데이터 데이터 영역 포인터 (동적 할당) 힙 동적 할당 영역 지역변수 스택 함수 내부 / 임시저장용
  26. 26. 여기부터 진짜로 포인터 이야기_
  27. 27. 포인터 (Pointer) 포인터는 주소를 저장하는 특이(特異)한 자료형입니다. 그리고 저장한 주소에 가서 값을 읽어옵니다. 그게 전부예요.
  28. 28. 포인터 (Pointer) 포인터는 주소를 저장하는 특별한 자료형입니다. 그리고 저장한 주소에 가서 값을 읽어옵니다. 그게 전부예요. 거짓말. 한 3% 정도 됩니다.
  29. 29. 포인터 (Pointer) 주소를 저장한다구요? 그럼,이게 다 뭔가요? 놀라지 말고 차근차근 하나씩 알아 봅시다 :D int *ptr; char *ptr; void *ptr; int **pptr; int *ptr[5]; int (*ptr)[3]; int (*foo)(double a);
  30. 30. 배우기 전에 그림을 그리기 위한 규칙을 배웁시다. 그림으로 그리면 조금 이해가 잘 됩니다. 제가 고심해서 만들…… 포인터 char int double struct
  31. 31. 일반 변수의 선언 및 초기화는 아래처럼 그릴 수 있습니다. int a = 20; 아래의 희미한 건 실제 저장되는 메모리의 시작주소입니 다. 20 a 0x080481AC
  32. 32. 포인터 변수는 주소를 저장하는 변수입니다. 형식은 타입 *변수명 이 됩니다. 변수 선언할 때 *는 어떤 변수가 포인터라는 것을 나타냅니다. 아래 선언 코드는 "ptr은 int의 포인터다" 라는 뜻입니다. ptr int *ptr;
  33. 33. 포인터에는 주소값이 저장됩니다. 이미 & 연산자를 이용해서 주소를 알아올 수 있으므로 사용해 봅시다. ptr int a = 20; int *ptr; ptr = &a; 20 a 0x080481AC 0x080481AC
  34. 34. 동그라미라서 칸이 모자랍니다. 어차피 a의 주소를 가르킨 거니까 그냥 화살표로 연결해 봅시다. a의 주소도 귀찮으니까 지웁니다. ptr int a = 20; int *ptr; ptr = &a; 20 a
  35. 35. 포인터가 가르키는 변수를 특별히 포인티라고 합시다. 다른 곳에서는 그렇게 안 부르는데 미국의 S대학 자료에서 발견한 멋진 이름입니다. 위 그림의 해석 "포인터 변수 ptr의 포인티는 int a이고 20이 저장되어 있다." ptr 20 a
  36. 36. 포인터 규칙1. 포인터와 포인티는 같은 타입이어야 한다.
  37. 37. 포인터에는 아무 주소나 들어갈 수 있을까요? 아닙니다. 포인터 규칙1. 포인터와 포인티는 같은 타입이어야 한다. ptr 20 a ptr은 int의 포인터라는 걸 그림만 봐도 알 수 있어요!
  38. 38. 포인터에는 아무 변수의 주소나 들어갈 수 있을까요? 아닙니다. 포인터 규칙1. 포인터와 포인티는 같은 타입이어야 한다. int a = 20; int *ptr; ptr = &a;
  39. 39. 문) 다음 코드에 문제가 없는지 그림으로 확인해 보세요. double *ptr1, *ptr2, dnum; dnum = 3.14; ptr1 = &a; ptr2 = ptr1;
  40. 40. 문) 다음 코드에 문제가 없는지 그림으로 확인해 보세요. double *ptr1, *ptr2, dnum; dnum = 3.14; ptr1 = &a; ptr2 = ptr1;
  41. 41. 문) 다음 그림을 코드로 나타내 보세요. ptr1 h c0 i c1 ptr2
  42. 42. 문) 다음 그림을 코드로 나타내 보세요. ptr1 h c0 i c1 ptr2 char c0 = 'h'; char c1 = 'i'; char *ptr1 = &c0; char *ptr2 = &c1;
  43. 43. 포인터 규칙2. 포인터 변수는 반드시 초기화 후에 사용해야 한다. 사실 그냥 변수도 그렇습니다.
  44. 44. 포인터의 사용을 위해서는 * 연산자를 사용합니다. 선언이 아닌 곳에서 *를 붙여서 포인티의 값을 읽거나 쓸 수 있습니다. int a = 20; int *ptr = &a; printf("%dn", *ptr) //*ptr이 int라는 걸 알겠죠? ptr 20 a ptr의 포인티는 a이므로 *ptr을 읽으면 20이 나옵니다.
  45. 45. 포인터를 사용하려면 * 연산자를 사용합니다. 선언이 아닌 곳에서 *를 붙이면 포인티의 값을 읽거나 쓸 수 있습니다. int a = 20; int *ptr = &a; printf("%dn", *ptr) //20 *ptr = 50; printf("%dn", *ptr) //50 printf("%dn", a) //? ptr 20 50 a *ptr에 50을 넣으면 자신이 아니라 포인티가 50이 됩니다. Make sense? Reasonable? LV?? 스마트 데이터
  46. 46. 포인터를 사용한다라는 건 결국 *을 사용한다는 것입니다. 그런데 초기화를 해 주지 않으면 포인티가 존재하지 않습니다. 아래 코드를 실행하면 어떻게 될까요? 그림으로 그리면? int *ptr; *ptr = 50; printf("%dn", *ptr) //? ptr
  47. 47. 초기화를 해 주지 않은 포인터는 절대 사용하면 안 됩니다. 그래서 초기화하지 않은 포인터는 아래처럼 그립니다. ptr LV.99 가비지 포인터 <엄청난 버그를 양산>
  48. 48. 다음 코드의 문제는 무엇인지 실행도 해 보고 그림으로 그려 봅시다. *참고로 맥에서 GCC로 컴파일하면 잘 실행됩니다. main() { int *ptr; foo(ptr); } void foo(int *p) { *p = 100; printf(“%dn”, *p); }
  49. 49. 포인터 규칙3. void*는 읽을 수 없다. 사실 그냥 변수도 그렇습니다.
  50. 50. void *란? 어떤 타입의 주소도 닮을 수 있는 만능 그릇 int도 double도 char도 누구라도 포인티가 될 수 있습니다!! 두 줄 동그라미로 그리도록 하겠습니다. ptr
  51. 51. To be continued…

×