1 / 23

메모리의 주소 (address) 메모리에는 일정 크기의 저장장소마다 위치를 나타내는 유일한 주소가 부여된다 . 주소 연산자 & 변수의 실제 메모리 주소를 구해줌

메모리의 주소 (address) 메모리에는 일정 크기의 저장장소마다 위치를 나타내는 유일한 주소가 부여된다 . 주소 연산자 & 변수의 실제 메모리 주소를 구해줌 변수의 실제 메모리 주소를 출력 %p : 주소를 16 진수로 출력 %u : 주소를 10 진수로 출력. int age; scanf (“%d”, &age);. 12FF7C, 1310588. int age; printf (“%p, %u”, &age, &age); . 포인터 (pointer) p.280

miette
Download Presentation

메모리의 주소 (address) 메모리에는 일정 크기의 저장장소마다 위치를 나타내는 유일한 주소가 부여된다 . 주소 연산자 & 변수의 실제 메모리 주소를 구해줌

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. 메모리의 주소(address) • 메모리에는 일정 크기의 저장장소마다 위치를 나타내는 유일한 주소가 부여된다. • 주소 연산자 & • 변수의 실제 메모리 주소를 구해줌 • 변수의 실제 메모리 주소를 출력 • %p : 주소를 16진수로 출력 • %u : 주소를 10진수로 출력 int age; scanf (“%d”, &age); 12FF7C, 1310588 int age; printf (“%p, %u”, &age, &age);

  2. 포인터(pointer) p.280 자료가 저장된 주기억 장소의 주소를 저장하는 변수즉 특정 주기억 장소를 가리키는 데 사용되는 변수 일반 변수 var1 int var1; 메모리 100000번지 포인터 변수 ptr int * ptr; 500 (데이터) 100000 (번지) ptr=&var1; 포인터는 자신이 가리키는 주소를 몰라도 어떤 변수를 가리키는 지만 알고 있으면 충분히 코딩할 수 있으므로 일반적으론 다음과 같은 그림으로 표현한다. var1 500 ptr

  3. 포인터 선언 p.281 • 예) int  var1=500; int * ptr; • 여러 포인터를 한꺼번에 선언하기 • int *ptr1, *ptr2, *ptr3; 자료형 * 포인터변수명; 포인터가 가리키는 곳에 저장된 자료의 형 int var1 int * ptr 500

  4. 포인터가 특정 변수를 가리키게 만들기 • 포인터에 가리킬 변수의 메모리 주소를 대입한다. 포인터 = &변수; • 예) int  var1; int *ptr; var1=500; ptr = &var1; // 포인터 ptr이 변수 var1을 가리키게 함 • 포인터를 선언과 동시에 초기화하기 • int *ptr = &var1; 주) ptr(포인터) var1(변수): 12FF7C 번지 ptr(포인터) var1(변수): 12FF7C 번지 12FF7C 500 int * ptr; ptr=&var1; int * ptr; *ptr=&var1;

  5. 예제 10.1 void main( ) {    char ch1 = 'A', ch2 = 'B';    char *ptr1, *ptr2;     ptr1 = &ch1;          ptr2 = &ch2;    printf("\n변수 ch1의 주소 : %u 번지“ , ptr1);    printf("\n변수 ch2의 주소 : %u 번지“ , ptr2); }

  6. 10.2 포인터와 관련된 연산 p.285 • 주소 연산자 & 변수의 실제 메모리 주소를 구해줌 ptr = &var1; • 간접 연산자(또는 역참조 연산자) * 포인터변수가 가리키는 기억장소를 의미 *포인터변수 ptr : ptr을 참조하라. *ptr : ptr에 저장된 주소에 해당하는 메모리를 참조하라. *ptr ptr 12FF7C 10 주) 실행문에서의 ‘*’는 포인터 선언의 *가 아닌 역참조를 의미 int * ptr;  포인터 선언 var = *ptr;  역참조

  7. ptr n : 12FF7C 번지 n=10; ptr=&n; printf(“%d”,n); printf(“%p”, ptr); printf(“%d”,*ptr); 10 변수 n에 저장된 값 포인터 변수 ptr에 저장된 값 • 포인터 ptr에 저장된 주소에 해당하는 기억장소에 저장된 값 즉 ptr이 가리키는 기억장소에 저장된 값 • ptr을 통한 간접적인 n의 참조

  8. 간접 연산자(또는 역참조 연산자) * 대입문의 왼쪽 변수 l-value:기억장소 int * ptr = &n; n=10; n = n + 1 ; *ptr = *ptr + 1; printf(“%d”,n ); printf(“%d”,*ptr); n = n + 1 ; • 대입문 오른쪽의 변수 • r-value :기억장소(변수)에 저장된 값 ptr n : 12FF7C 번지 10 위의 결과 printf(“%d”,n );  12 printf(“%d”,*ptr);  12 r-value (ptr이 가리키는 기억장소에 저장된 값)과 (1)을 더한 결과를 (ptr이 가리키는 기억장소)에 대입

  9. 출력 결과는? int sum =0; int *ptr1, *ptr2; // 선언 ptr1 = ∑ printf(“%d\n”, sum); printf(“%d\n”, *ptr1); printf(“%u\n”, &sum); printf(“%u\n”, ptr1); *ptr1= 1; printf(“%d\n”, *ptr1); *ptr1 = *ptr1 * 10; printf(“%d\n”, *ptr1); ptr2 = ptr1; (*ptr2)++; // *ptr2 = *ptr2+1; printf(“%d, %d\n”, *ptr1, *ptr2); ptr1 ptr2 sum : 100번지 0

  10. fp sp first second temp 20 10 포인터 실습 • first, second의 내용을 int형 포인터 fp, sp를 이용하여교환하기 int first=20; int second=10; int *fp, *sp; 교환전의 first, second를출력하기 fp, sp를 이용 first, second 교환 교환후의 first, second 값을포인터 fp, sp를 이용출력

  11. 10.4 포인터와 함수 (인수 전달) • call by value • 함수가 호출될 때 가인수의 메모리가 할당되며 실인수의 값만 가인수에 전달되어 저장됨 • 함수 안에서 가인수의 값을 바꾸어도 함수 종료 후 호출한 곳으로 돌아 갔을 때 실인수의 값은 호출전과 같음  함수간의 독립성 보장 • call by address • 함수의 가인수로 포인터 변수를 이용하는 방식 • 함수가 호출될 때 가인수의 메모리(포인터로 4바이트)가 할당되며 실인수의 주소가 전달되어 저장됨 • 함수 안에서 가인수(포인터)를 이용하여 실인수의 내용을 변경할 수 있다. • 친구에게 수업 노트를 빌려줄 때 • 노트 원본을 빌려주는 것 (주소호출)노트를 복사하여 복사본을 갖게 하는 것 (값 호출)

  12. call by address 함수명( 실인수의 주소 ) • 함수 호출시 int a = 10; func(&a); a를 출력하면? • 함수 정의시 void func(int * ptr) { *ptr = 20; } a 10 12FF78번지 리턴형 함수명( 자료형 * 가인수 ) { 함수 본체 } ptr 12FF78 실인수의 자료형과 동일

  13. 100 200 a b x y p.298 예제 10.10 주소에 의한 호출(call by address):두 변수의 값 교환 * * 책 수정하기 void int_swap(int __ x, int __ y ); //원형 선언 void main( ) { int a=100, b=200; printf(“교환전: %d, %d \n”, a, b); int_swap(___a, ___b); printf(“교환후: %d, %d \n”, a, b); } void int_swap(int ___ x, int ___ y) { int temp; temp = ___x; ___x = ___y; ___y = temp; } & & * * * * * * temp

  14. 배열명 intvalue[N] = {90, 80, 70, 90, 100}; division(value); for (i=0; i<N; i++) printf(“%d”, value[i]); void division( intary[N]) { inti; for (i=0; i<5; i++) ary[i] = ary[i]/10; } 결과는? • division 함수에서는 ary이름의 배열로서 사용하면 된다. main 함수와 같은 기억공간을 공유하게 되므로 division에서 배열 내용을 수정하고 main으로 돌아오면 main의 value 배열의 내용도 바꿔져 있게 된다.

  15. value • 배열명은 배열의 첫번째 원소를 가리키는 포인터 int value[] = {90, 80, 70, 90, 100}; division(value); for (i=0; i<5; i++) printf(“%d”, value[i]); void division( int * ary) { inti; for (i=0; i<5; i++) ary[i] = ary[i]/10; } • division 함수에서는 ary를배열이름으로 사용하면 된다.

  16. 최대치는 max에 최대치의 배열 첨차는 index에 저장이 되게 하려면? • void main() { • int score[N] ={90,99,51,60,70}; • inti, max, index; • max=maximum(_________, &index); • printf("최대치: score[%d]=%d ", • index, max); • } #include <stdio.h> #define N 5 void main() { int score[N]={90,99,51,60,70}; inti, max, index; max= score[0]; index=0; for ( i=1 ; i< N ; i++) { if (max < score[i]) { max = score[i]; index = i; } } printf("최대치: score[%d]=%d ", index, max); } // 전달된 배열의 최대치는리턴하고 최대치의 // 배열 첨자는 main의 index에저장되도록 // index를 가리키는 포인터 which를 선언 intmaximum( 배열선언 , int *which ) { int max; *which = 0 ; //첨자를 0으로 초기화 : }

  17. 포인터 변수에는 사용자가 직접 주소를 저장할 수 없다. • NULL 상수는 예외 int *ptr = 10000; ---(X) int *ptr = NULL; ---(O) • NULL 상수 포인터의 초기화 값으로 주로 사용되며 포인터가 어떤 메모리도 가리키고 있지 않다는 의미로서 이용됨 char * ptr=NULL; : // 특정 학생의 이름을 찾아서 ptr이 가리키게 하는 코드 if ( ptr == NULL ) { printf(“ 그런 사람은 없습니다.”);

  18. int * n 1 2 3 4 5 6 • 포인터 + 1 또는 포인터 -1 포인터의 ‘형’ 에 따라 증가(감소)되는 값이 달라진다. 즉 포인터가 가리키는 자료형이 실제로 메모리를 차지하는 크기만큼 증가됨 int형 포인터  4 double형 포인터  8 char형 포인터  1 n++ 후? n 형 *포인터; : 포인터++;  포인터는 바로 다음 자료가 저장된 장소를 가리키게 됨

  19. 95 88 76 54 85 82 • 배열명 • 배열의 첫번째 원소를 가리키는 포인터 • int point[] = {95, 88, 76, 54, 85, 82}; point에 저장된 100번지를 참조 (100+1·4)번지를 참조 point 100번지 • 결과는? • printf(“%d \n”, *point); • printf(“%d \n”, *(point+1)); • printf(“%d \n”, *(point+2)); 100(번지) 95 88 76 (100+2·4)번지를 참조

  20. 111 222 333 444 a 555  6 :  int a[5] = {111, 222, 333, 444, 555 };  7 :  int *p = a;  // int * p; p=1;  8 :  int i; 15 : 16 : for(i=0; i<5; ++i) { 17 :    printf(“ … %d, … %d",  a[i], *(p+i) );  19 :  }  20 :  p

  21. value • 14번 슬라이드를 포인터 이용하여 수정하기 int value[] = {90, 80, 70, 90, 100}; division(value); for (i=0; i<5; i++) printf(“%d”, value[i]); void division ( int * ary) { inti; for (i=0; i<5; i++) *(ary+i) = *(ary+i) / 10; } 14번 슬라이드의 ary[i] = ary[i]/10;

  22. 포인터를 이용한 변수 내용 교환 fp=&first; sp=&second; temp = *fp; *fp = *sp; *sp = temp; • 이처럼 두 변수 first, second를 직접 이용하지 않고 포인터 fp, sp를 이용하여 두 변수의 내용을 간접적으로 참조하여 교환시킬 수 있다.

  23. void main() { int n1 = 10, n2 = 20; int *ptr1, *ptr2, *temp; ptr1 = &n1; ptr2 = &n2; printf("%3d", n1); printf("%3d", *ptr1); n1 = 30; printf("%3d", n1); printf("%3d", *ptr1); *ptr1 = *ptr2 + 5; printf("%3d", n1); printf("%3d", *ptr1); temp = ptr1; ptr1 = ptr2; ptr2 = temp; n1 = 10; n2 = 20; printf("%3d", n1); printf("%3d", n2); printf("%3d", *ptr1); printf("%3d", *ptr2); }

More Related