포인터는 변수이다. 포인터는 메모리 번지를 저장하는 변수이다. 다음 정의에서
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를 함수 포인터로 먼저 캐스팅한 후 함수화
}
'프로그래밍 > C' 카테고리의 다른 글
Vi 편집기 setting (0) | 2013.04.19 |
---|---|
linux kernel에서 쓰이는 자료구조.(double linked list and tree) (0) | 2013.04.19 |
Double linked list with using array (0) | 2013.04.19 |
함수 포인터 (0) | 2013.04.19 |
linked list [펌] (0) | 2013.04.19 |