- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 재능이의 돈버는 일기
- StresslessLife
- K_JIN2SM
- 소소한 일상
- My Life Style & Memory a Box
- Blog's generation
- 공감 스토리
- 취객의 프로그래밍 연구실
- Love Me
- Dream Archive
- 세상에 발자취를 남기다 by kongmingu
- hanglesoul
- 카마의 IT 초행길
- 느리게.
- 미친듯이 즐겨보자..
- Joo studio
- Gonna be insane
- 악 다 날아갔어!! 갇대밋! 왓더...
- xopowo05
- 맑은공기희망운동
- 엔지니어 독립운동
- 혁준 블로그
- Simple in Complex with Simple
- 무의식이 의식을 지배한다
드럼치는 프로그래머
[C] 포인터, 배열, 구조체 본문
고급 C/C++ 언어 프로그래머가 가장 많이 사용하는 것이 포인터다. 잘만 사용하면 효율적인 프로그램 도구가 될 수 있으나, 일반 사용자 입장에서는 그만큼 이해하기 어려운 개념이 바로 포인터다. 배열과 구조체는 데이터 여러 개를 묶었다는 의미에서 군집 데이터 타입이라 불린다. 이 두 가지는 기본적인 자료구조 형태로서 중요한 역할을 한다.
01 포인터
포인터란 문자 그대로 어떤 변수를 가리키는 것을 말한다.
포인터는 그것이 가리키는 변수의 주소 값을 저장한다.
포인터 변수에는 주소 값만이 저장 될 수 있다.
포인터를 일명 핸들이라고도 한다.
1_ 동적 메모리 할당
메인 메모리의 모든 변수에는 주소 값이 있다.
int *p;는 "p가 가리키는 것은 정수 타입"이라는 뜻이다. 애스터리스크(Asterisk, *)는 참조의 대상을 찾아내는 연산자로서 Something pointed by의 의미다. 따라서 int *p;는 'Something pointed by p is of type integer'로 해석하면 된다.
*p=15;
가리키는 변수가 없는 상태에서 그걸 따라 가서 그 변수 값을 할당하라는 것은 오류이다. 가리키는 변수가 없이 포인터가 가리키는 곳에 값을 넣으려면 아래처럼 해줘야 한다.
p=(int *)malloc(sizeof(int));
*p=15;
malloc 함수는 C의 붙박이(Built-in) 함수로서 메모리 할당의 의미다.
이처럼 이름이 없는 변수지만 포인터에 의해 조작될 수 있는 변수를 익명 변수라 한다.
C의 malloc 함수에 해당하는 것이, C++의 new 함수다. 따라서 위 두번째 명령어를 p=new int; 하고 하면 된다.
이 같은 공간은 프로그램 실행 중에 만들어진다. 예를 들어, int Date, Month; 처럼 선언에 의해 만들어지는 변수는 프로그램이 시작될 때 이미 각 변수를 위한 메모리 공간과 주소가 할당된 상태에서 시작한다. 이른바 정적 메모리 할당이다.
malloc(또는 new)에 의해 만들어지는 공간은 해당 명령어가 실행되는 순간에 만들어지는, 동적 메모리 할당이다.
실행 전부터 예상되는 변수 모두를 선언하는 정적인 메모리 할당에 비해 동적 메모리 할당이 메모리 공간을 더 효율적으로 활용할 수 있다. 주의해야 할 것은 int *p; 선언에 의한 포인터 변수 p는 여전히 정적인 메모리라는 점이다. 여기서 동적인 메모리는 malloc에 의해 이 포인터에 매달리는 변수 공간을 말한다.
필요에 의해 동적 메모리 공간을 만들었다면 그 공간을 반납하는 것도 프로그래머의 책임이다.
포인터에 의해 만들어진 변수 공간을 반납하기 위한 C 명령어가 free라면 C++에서의 명령어는 delete다. 예를 들어, 포인터 p가 가리키는 변수 공간을 반납하려면 C언어에서는 free p;라고 하면 되고, C++에서는 delete p;라고 하면 된다.
해제에 의해 p가 가리키는 변수공간은 운영체제에 반납되었지만 포인터 변수 p의 자체 공간은 프로그램이 끝날 때까지 반납되지 않는다.
만약 해제한 동적메모리를 가리키고 있는 포인터 변수 p의 값이 여전히 자신의 주소값을 가지고 있다고 해서, 포인터를 따라가서 그 값을 건드린다면 이것은 문제가 된다. 즉, 이미 반납되어 운영체제가 다른 프로그램을 위해 사용할지도 모르는 메모리 공간을 찾아가는 꼴이 된다.
일반적으로 이러한 시도는 접근 위반으로 오류 처리된다. 오류를 예방하려면 free에 의해 공간을 반납한 포인터에는 항상, 그 즉시 널(NULL)이라는 값을 넣는 것이 좋다.
free (p); // p가 가리키는 변수 공간을 반납
p=NULL; // p를 따라가지 않도록
2_ 주소 연산자
int Date, Month;
int *p;
p=&Date;
여기서 주소 연산자 앰퍼샌드(Ampersand, &)는 'Address of' 라는 뜻을 지니고 있다.
할당문의 오른쪽에 올 수 있는 표현을 RValue, 왼쪽에 올 수 있는 표현을 LValue라고도 한다.*p는 LValue로도 사용될 수 있고 RValue로도 사용된다. 예를 들어, *p=15; 라고 표현하면 "p가 가리키는 변수에다 15라는 값을 할당하라"라는 의미고 date=*p; 라고 하면 "현재 p가 가리키는 변수 값을 date라는 변수에 할당하라" 라는 의미다.
앰퍼샌드(&) 연산자는 애스터리스크(*) 연산자와 서로 역함수 관계에 있다.
연산자 두개가 서로 역함수라 함은 서로의 기능이 정반대라는 의미다.
*&date=15;
좌변은, 정확히는 *(&date)로써, "변수 date 의 주소 값을 가리키는 것"을 의미한다. 변수 date의 주소 값이 가리키는 것은 당연히 변수 그 자체다. 즉, 변수를 주소 값으로 매핑시키는 함수가 앰퍼샌드(&)고, 역으로 주소를 그 주소가 가리키는 변수로 매핑시키는 함수가 애스터리스크(*)다.
3_ 저네릭 포인터
정수 포인터에 문자 포인터를 할당하는 것을 오류라 할 수 있다.
저네릭 포인터란 제너럴 즉 일반적인 포인터를 의미한다.
포인터 변수명을 Ptr이라고 하면 저네릭 포인터는 void *Ptr;에 의해 선언된다.
Ptr=(float *)malloc(sizeof(float));
여기서 (float *)는 포인터 타입을 부동소수 포인터로 변경시키라는 뜻의 타입변환 연산자다. 만약, Ptr이 저네릭 포인터라면 이러한 타입변환 연산자를 반드시 사용해야 된다. 만약 Ptr이 float *Ptr;로 선언되었다면 Ptr 자체가 이미 부동소수를 가리키는 포인터므로 위의 할당문에서 (float *)는 없어도 된다.
4_ 댕글링 포인터, 가비지
포인터에 의해 생성된 동적 메모리 공간을 반납할 때에는 댕글링 포인터(Dangling Pointer, 매달린 포인터)에 유의해야 한다.
이미 반납된 공간에 줄을 대고 있는 이러한 포인터를 댕글링 포인터라고 한다. 비유적으로 말하면 이미 이사 간 옛 집에서 친구를 찾는 격이다.
int *p, *q;
p=(int *)malloc(sizeof(int));
q=(int *)malloc(sizeof(int));
*p=5; *q=20;
p=q;
위의 코드처럼 무작정 연결을 끊어버리면 이전에 가리키던 공간은 반납되지 않은 상태로 머물게 된다. 이렇나 메모리 공간을 가비지(쓰레기)라고 한다.
5_ 상수 포인터
포인터가 가리키는 데이터가 변하지 않도록 선언할 수 있다.
포인터명을 Ptr이 가리키는 변수 a의 값이 변하지 않도록 하려면 다음과 같이 선언하면 된다.
int a=24;
const int* Ptr=&a;
포인터 자체의 값이 불변이 되도록 선언할 수도 있다. 즉, 포인터가 항상 동일한 메모리 주소를 가리킴으로써 원치 않게 다른 포인터 값이 할당되는 것을 방지하기 위한 것이다.
int* const Ptr=new int;
int a;
*Ptr=25;
Ptr=&a;
물론, 이 경우에는 포인터 값이 불변이라는 것이지 그 주소 안에 있는 변수 값이 불변이라는 것은 아니다.
배열 변수에 있어서 배열명은 그 배열의 첫번째 요소를 가리키는 포인터다.
배열명은 본질적으로 상수 포인터라 할 수 있다.
'★─Programing > ☆─C | C++' 카테고리의 다른 글
[C] strtok구현 (0) | 2007.11.07 |
---|---|
[C] 2차원 배열 생성 malloc (0) | 2007.10.30 |
[C] strstr 함수 (0) | 2007.10.29 |
[C] Swich문과 If 문 비교 (0) | 2007.10.21 |
[C] 파일입출력 > 파일의개방,종결 기본소스 (0) | 2007.09.06 |