카테고리 없음

[C특강] 변수와 포인터의 관계

카카오블로거 2021. 12. 30. 19:12

포인터는 변수이다. 포인터는 메모리 번지를 저장하는 변수이다. 다음 정의에서

  int   i;

  int* pi;

는 모두 변수이다. 차이점이 있다면 i는 값을 저장하기 위한 변수이고, pi는 메모리 번지를 저장하기 위한 변수이다.

i 및 pi가 차지하는 메모리 공간은 4바이트이다. 그렇다면 두 변수는 서로 성질은 틀리지만 값을 교환할 수 있다.

다음은 i 및 pi의 사용이다.

  int   i;

  int* pi;

  i = 50;

  pi = &i;          // 변수 pi에 i의 번지값을 대입

  pi = (int*)i;    // 변수 pi에 i의 값을 대입

위 코드에서 pi는 i의 번지가 아닌 i의 값을 갖게 된다.

  int   i;

  int* pi;

  i = 50; 

  pi = (int*)i;              // 변수 pi에 i의 값을 대입, pi는 i의 값 50을 메모리 번지로 대입 받는다.

  printf( "%d ", pi );   // 50이 출력, 변수 pi의 값을 출력하기 때문에

  *pi = 30;          // pi는 i의 값 50을 갖고 있으므로, *pi는 50번지를 접근하게 된다.

                            // 메모리 번지 50번지는 일반적으로 접근할 수 없는 번지이니까 프로그램 다운된다.

                            // 만약 i가 50이 아니라 특정 변수의 주소값이었다면, 그 특정 변수에 접근은 가능할

                            // 것이다.

결국 존재하지 않는 임의의 번지를 위와 같이 pi에 넣을 수는 있지만, 옳지 않은 번지를 접근함으로써 프로그램은

다운된다. 그렇기 때문에 C 언어는 이를 다음과 같이 직접 대입할 경우 경고 에러(Warning Error)를 발생시킨다.

   pi = i;      // warning C4047: '=' : 'int *' differs in levels of indirection from 'int '

정리하면, 포인터 변수와 일반 데이터 변수간에는 그 값을 맞교환할 수 있지만, 그 사용에 있어서는 주의를 해야 한다.

다음 코드는 어떨까? 내가 나의 번지를 갖고 있다가 나한테 접근해서 값을 바꾼다.

  int  i = 5;

  i = (int)&i;      // i에 i의 번지를 대입
  printf( "i의 주소는 %#X \n", i );   // i의 주소는 0X12FF7C

  *(int*)i = 100;
  printf( "i의 값은 %d \n", i );
          // i의 값은 100

다음 코드는 함수 포인터를 대신해서 사용되는 i 변수이다. 변수 i는 4바이트 크기를 갖기 때문에 함수 포인터로 동작할

수 있다.

  #include <stdio.h>

  int count = 0;

  void main( void )
  {
      int  i;

      i  =  (int)main;

      printf( "%d ", count++ );

      ( (void(*)(void)) i ) ();   // main() 함수를 직접 호출하는 것과 동일

                                                 // i를 함수 포인터로 먼저 캐스팅한 후 함수화
  }