|
http://www.hackerschool.org/HS_Boards/zboard.php?AllArticle=true&no=7867 [복사]
C가 강력한 이유중 하나가 이 포인터 때문입니다.
# 포인터가 도대체 무엇?
포인터의 정확한 이름은 '포인터형 변수' 입니다.
그냥 줄여서 포인터라고 하는 것이죠.
그럼 여기서 포인터는 변수라는걸 아셨겠죠?
변수에는 정수 형태, 장정수, 부동 소숫점 수, 문자 형태 등등이
있습니다. 그럼 포인터는 도대체 어떤 형태 일까요?
포인터는 바로 주소 형태 입니다. 그러니까 정수도 아니고,
문자도 아닌 메모리의 주소를 기억시키는 변수라는 것이죠.
포인터는 변수이고, 변수 중에서도 주소를 기억시키기 위한
변수라는 것을 꼭 기억해 두시면 다음은 잘 이해가 되실 겁니다.
# 포인터는 어떻게? 선언을..
변수는 사용전에 선언을 해 주어야 합니다.
포인터 역시 변수 이므로 선언을 해 주어야 하겠죠?
포인터의 선언은 다음과 같이 합니다.
7
데이터형태* 포인터이름;
아까 포인터는 주소를 기억시키는 변수라고 했습니다.
그런데 주소에도 종류가 있죠?
정수 형태 변수의 주소, 문자 형태 변수의 주소 등등..
이런 어떤 형태의 주소인지를 지정해 주는 것이 데이터형태 입니다.
만약 주소의 형태가 특별히 정해져 있지 않았다면 void를 씀니다.
void를 써서 포인터를 선언하면 어떤 형태의 주소든지 넣을수 있죠.
그리고 *는 그 변수가 포인터임을 알리기 위해 써 주는 것이고,
포인터이름은 그 포인터를 상징하는 심볼입니다.
예를 들어 정수 형태의 변수의 주소를 넣는 포인터는
int* Pointer;
이렇게 선언합니다.
포인터 선언시 *의 위치는 데이터형태와 포인터이름 사이에라면
어느 곳에 와도 상관 없습니다.
예를 들어 아까 Pointer라는 변수는
int * Pointer;
이렇게 선언해도 되고,
int *Pointer;
이렇게 선언해도 상관 없습니다.
# 포인터 연산자
C언어 에서는 포인터 사용시에 사용하는 연산자가
2가지가 있습니다. 그 두가지는 기존의 비트별 논리곱 연산자인
&와 곱셈 연산자인 *입니다.
포인터 연산자로 쓰일때 &는 주소 연산자라고 하고,
*는 참조 연산자라고 합니다.
(1) 주소 연산자
주소 연산자(&)란 어떤 변수의 주소를 얻는 연산자를 말합니다.
사용법은 주소를 얻고자 하는 변수의 앞에 &를 붙여 주기만 하면 됨니다.
그러니까
포인터 = &변수;
이렇게 하면 변수의 주소가 포인터에 들어가죠.
예를 들어
int Variable=10;
int *Pointer;
이렇게 두 변수를 선언했다고 할때,
Pointer = &Variable;
이렇게 해 주면 Variable라는 변수의 주소가 Pointer라는 변수로 들어갑니다.
이것을 실제 메모리 상의 구조를 통해 다시한번 살펴보죠.
처음에
int Variable=10;
int *Pointer;
이렇게 변수를 선언할 당시는
변수이름 | Variable Pointer
주소 | 1 2 3 4 . . .
---------+--------------------------------------------
값 | 10 ? ? ?
다음과 같은 메모리 구조를 갖습니다.
여기서 Variable라는 변수는 실재 메모리 주소 1을 할당받았다고 하고,
Pointer라는 변수는 실재 메모리 주소 3을 할당받았다고 합시다.
다음에
Pointer = &Variable;
이렇게 하면 Pointer라는 변수에 Variable의 주소인 1이 들어가서
변수이름 | Variable Pointer
주소 | 1 2 3 4 . . .
---------+--------------------------------------------
값 | 10 ? 1 ?
이렇게 됨니다.
(2) 참조 연산자
포인터는 주소를 기억시키는 변수라는 것을 이미 배웠습니다.
그렇다면 그 기억시키고 있는 주소에 기억되어 있는 값을 사용하거나
다른 값으로 바꿀땐 어떻게 할까요? 그때 참조 연산자인 *를 사용 합니다.
사용법은
*포인터 = 값;
변수 = *포인터;
이런 식으로 사용하죠.
첫번째의 경우 포인터에 저장되어 있는 주소에 값을 넣어 줌니다.
두번째의 경우는 포인터에 저장되어 있는 주소에 기억되어 있는 값을
변수로 넣어 주게 되겠죠?
예를 들어..
int Var1=10, Var2;
int *Pointer;
이렇게 세개의 변수를 선언했고,
Pointer = &Var1;
이렇게 Pointer에 Var1의 주소를 넣었다고 합시다.
이때
*Pointer=5;
이렇게 해 주면 Pointer에 저장되어 있는 주소 즉
Var1이라는 변수의 주소에 5를 넣어 주므로 결국에는 Var1은 5가 됨니다.
그 다음으로
Var2=*Pointer;
이렇게 했다면 Pointer에 저장되어 있는 주소에 들어있는 값,
즉 Var1라는 변수의 주소에 들어있는 값인 5가 Var2에도 들어가
Var1, Var2가 모두 5가 되죠.
이걸 실재 메모리 구조를 보며 다시한번 살펴 볼까요?
처음에
int Var1=10, Var2;
int *Pointer;
이렇게 세개의 변수를 선언할 당시는
변수이름 | Var1 Var2 Pointer
주소 | 1 2 3 4 . . .
---------+--------------------------------------------
값 | 10 ? ? ?
다음과 같은 메모리 구조를 갖는데,
여기서 Var1라는 변수는 실재 메모리 주소 1을 할당받았고,
Var2라는 변수는 실재 메모리 주소 2를, Pointer라는 변수는
메모리 주소 4을 할당받았다고 합시다.
이때
Pointer = &Var1;
이렇게 Pointer라는 변수에 Var1의 주소인 1을 넣어주면
변수이름 | Var1 Var2 Pointer
주소 | 1 2 3 4 . . .
---------+--------------------------------------------
값 | 10 ? ? 1
이렇게 되겠죠?
그리고 다음으로
*Pointer=5;
이렇게 해 주면 Pointer에 기억되어 있는 주소 즉 1이라는 주소에
5를 넣어 주어
변수이름 | Var1 Var2 Pointer
주소 | 1 2 3 4 . . .
---------+--------------------------------------------
값 | 5 ? ? 1
이렇게 됨니다. 그러므로 Var1의 값은 5로 바뀌게 됨니다.
마지막으로
Var2=*Pointer;
이렇게 하면 Pointer에 저장되어 있는 주소
즉 1이라는 주소에 들어있는 값인 5가 Var2에도 들어가
변수이름 | Var1 Var2 Pointer
주소 | 1 2 3 4 . . .
---------+--------------------------------------------
값 | 5 5 ? 1
이렇게 Var1과 Var2에 모두 5가 들어가게 되죠.
# 포인터에 초기값 주기.
변수는 선언시에 초기값을 줄수 있었죠?
그런데 포인터도 변수이므로 당연히 초기값을 줄수 있겠죠?
포인터에 초기값을 주는 방법은 일반 변수와 똑같습니다.
그러니까
int* Pointer=1;
이렇게 하면 1이라는 주소를 초기값으로 준 것이죠.
그런데 뭔가 이상하죠?
주소는 자기 마음데로 정하는게 아니거든요.
그래서 저렇게 선언하는 사람을 '바보'라고 하죠.
일반적으로 포인터에 초기값을 줄 때는
데이터형 변수;
데이터형* 포인터이름 = &변수;
이렇게 합니다.
우선 변수를 선언하고 그 변수의 주소를 초기값으로 주는 것이죠.
예를 들어
int Variable;
int* Pointer=&Variable;
이렇게 하면 Variable라는 변수의 주소가 Pointer라는 포인터에
초기값으로 들어갑니다.
# 다시한번 포인터에 대해 정리.
포인터에 대해 다시한번 정리를 해 보죠.
우선 포인터는 변수이고, 변수 중에서도 주소를 기억시키는 변수 입니다.
포인터 선언은
데이터형태* 포인터명;
이렇게 해 주면 되고, 여기서 데이터형태는 그 포인터가 어떤 형태의
변수의 주소를 넣는 것인지를 지정하는 것이었죠?
다음으로 포인터 연산자에는 주소 연산자(&)와, 참조 연산자(*)가 있는데,
주소 연산자는 어떤 변수의 실제 주소를 얻고자 할때 사용하는 것으로
주소를 얻고자 하는 변수 앞에 붙여 주기만 하면 되고요.
참조 연산자는 포인터에 저장되어 있는 주소에 기억되어 있는
데이터를 변경시키거나 사용할때 쓰는 것으로, 포인터의 앞에
붙여 주기만 하면 됨니다.
예를 들어
int Variable;
int* Pointer;
이렇게 변수 두개가 있을때,
Pointer=&Variable;
이렇게 하면 Pointer라는 포인터에는 Variable라는 변수의
주소가 들어가고
*Pointer=10;
이렇게 하면 Pointer에 들어있는 주소 즉 Variable의 주소에 들어있는
값이 변경되므로 결국은 Variable가 변경되어 10이 들어가게 되죠.
마지막으로 포인터에 초기값을 줄때는 일반 변수와 똑같으나
주소는 마음데로 정하는 것이 아니므로 일반적으로
일단 변수를 선언하고 포인터에는 그 변수의 주소를 초기값으로 줍니다.
예를 들어
int Variable;
int* Pointer=&Variable;
이런 식으로.
그럼 예제를 하나 보죠.
/* 파일 이름 : C9-1.C
프로그램 내용 : 포인터 예제. */
#include <stdio.h>
void main()
{
int Var1, Var2;
int *pVar=&Var1;
*pVar=10;
printf("%d\n",Var1);
Var2=*pVar;
printf("%d\n",Var2);
pVar=&Var2;
*pVar=5;
printf("%d\n",Var2);
}
한번 잘 분석해 보세요. 어떤 결과가 나올까요?
결과는
C:\>C9-1.EXE
10
10
5
[출처] 제트스윙 블로그 - http://www.zetswing.com
|
Hit : 11618 Date : 2013/05/06 02:36
|