ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20140327 (포인터, 배열, call by address, call by value)
    부산IT학원/스마트컨트롤러 2014. 3. 27. 15:20

    29일차

     

     

    --------------------------------------

    포    인    터      ,     배    열

    ---------------------------------------

     

    ---------------------------

    --- 포인터 사용시 주의할 점.

     

    int  iNum = 10;
    double *  dpNum = &iNum;  // Warning!

    double  dNum = 10.5;
    int *  ipNum = &dNum;  
    // Warning!

    같은 포인터 타입이기에 Error는 안나서 실행은 되지만

    다른 자료형(실수, 정수)이므로 Warning입니다.

    상황에 따라 어떤 오류가 발생할지는 모르니 잘못된 것입니다.

     

    int *  ipNum;

    *ipNum = 1000// Warning!

    ipNum에 주소값도 정해져 있지 않은데 그 주소값에 저장된 값을 바꾸면

    어떤 문제가 발생할지 모르니 이것도 잘못된 것. warning, 런타임 에러

     

    int *  ipNum = 1000;

    *ipNum = 10;

    ipNum에 1000번지를 넣었는데 1000번지가 어딘지 알고 넣었는지?

    또 그 값을 변경도 시켰으니 Warning, 런타임 에러

     

    int *  ipNum1 = 0;
    int *  ipNum2 = NULL;

    포인터는 NULL (0) 으로 초기화 값으로 주는게 좋다고 합니다.

    그래서 아래 코드를 시험해 보니

    #include <stdio.h>

    int main()
    {
      int *  ipNum = NULL;

      *ipNum = 10;

      return 0;
    }

    초기화 값을 뭘 주든 제대로된 주소가 아니면 런타임 오류가 납니다.

     

     

     

    ----------------

    --- 포인터 연산

     

    출력 화면

    포인터를 연산할 경우 그 자료형 만큼 주소값이 움직입니다.

    char * cpNum = 1000;

    cpNum = cpNum + 2;    =>   1000 + 2 * 1byte   =>   1002   (2byte움직임)

    int * ipNum = 2000;

    ipNum = ipNum + 2;    =>    2000 + 2 * 4byte   =>   2008   (8byte움직임)

    double * dpNum = 3000;

    dpNum = dpNum + 2;    =>   3000 + 2 * 8byte    =>    3016   (16byte움직임)

     

     

     

    -----------------------

    --- *(ipNum+0) == arr[0]

     

    배열도 포인터도 주소값을 저장하고 있어서

    사용법도 비슷합니다. 그래서

    *(ipNum+0) == arr[0]    <-- 이 등식이 성립합니다.

     

    ex)

    int main()
    {
      int  arr[3= {112233};
      int *  ptr = arr;

      printf("arr[0] : %d \n", arr[0]);
      printf("arr[1] : %d \n", arr[1]);
      printf("arr[2] : %d \n", arr[2]);

      printf("ptr[0] : %d \n", ptr[0]);
      printf("ptr[1] : %d \n", ptr[1]);
      printf("ptr[2] : %d \n", ptr[2]);

      printf("*(arr + 0) : %d \n", *(arr + 0) );
      printf("*(arr + 1) : %d \n", *(arr + 1) );
      printf("*(arr + 2) : %d \n", *(arr + 2) );

      printf("*(ptr + 0) : %d \n", *(ptr + 0) );
      printf("*(ptr + 1) : %d \n", *(ptr + 1) );
      printf("*(ptr + 2) : %d \n", *(ptr + 2) );

      return 0;
    }

    출력 화면

    *(ipNum+0) == arr[0]    <-- 이 등식이 성립합니다.

     

     

     

     

    ------------------------------------

    --- char str1[] = "My String";
         char * str2 = "Your String";  장단점

     

    여기서 str2 포인터 변수는 스택에 변수를 가리키는게 아니라

    소스에 저장된 Your String을 가리킨다는 것을 명심!

     

    배열

    메모리 더 먹음, 수정 가능.

    포인터

    메모리 4byte만 먹음, 수정 불가.

     

     

     

     

     

    --- 포인트 배열

    포인트 타입의 배열이다.

    ex)

    arr 배열에 0, 1, 2 주소에 각각 주소값이 저장되어 있습니다.

    printf("%d \n", *arr[0] );

    ->  printf("%d \n", *0x1000 );

    ->  printf("%d \n", 10 );

    이런 과정을 거치겠죠....

     

     

     

     

    --- 함수의 인자로 배열로 받을 수 없다.

    그래서 포인터로 받는다.

    ex)

     

     

     

     

     

    --- Call by Address, Call by Value

    함수에 인수를 다룰 때 쓰는 방법.

    -   Call by Address     : 주소를 넘겨 호출.

    -   Call by Value         : 을 넘겨 호출.

    ex) 예제 소스

    #include <stdio.h>

    void CallByValue(intint);
    void CallByAddress(int *, int *);

    int main()
    {
      int  iNum1 = 10;
      int  iNum2 = 100;

      CallByValue(iNum1, iNum2);  //  Call By Value
      printf("CallByValue() -> %d %d \n", iNum1, iNum2);

      CallByAddress(&iNum1, &iNum2);  //  Call By Address
      printf("CallByAddress() -> %d %d \n", iNum1, iNum2);

      return 0;
    }

    void CallByValue(int n1, int n2)
    {
      int  iTemp;

      iTemp = n1;
      n1 = n2;
      n2 = iTemp;
    }

    void CallByAddress(int * n1, int * n2)
    {
      int  iTemp;

      iTemp = *n1;
      *n1 = *n2;
      *n2 = iTemp;
    }

    출력 화면

     

    CallByValue 는 말 그대로 main에 있는 변수의

    가져와 쓰기 때문에 CallByValue 에서 무슨 짓을 해도

    main의 변수에 접근할 수 없다.

     

    CallByAddress 는 말 그대로 main에 있는 변수의 주소값

    가져와 쓰기 때문에 CallByAddress 에서 무슨 짓이든

    main의 변수에 접근할 수 있다.

     

     

     

Designed by Tistory.