레퍼런스는 자동적으로 역참조되는 포인터라고 할 수 있다. 자동적 역참조(automatically dereferenced)라는 것은 레퍼런스의 값을 얻기 위해 역참조 연산자 *를 사용할 필요가 없음을 의미한다. 레퍼런스는 다른 변수를 위한 별명(aliases)을 만든다. int i = 20; //일반 정수형 변수 int *ip = &i; // 정수형에 대한 포인터 int & ir = i; // 정수형에 대한 레퍼런스 레퍼런스를 정의 하기 위해 주소 연산자, &를 사용한다. 레퍼런스를 초기화하지 않고 레퍼런스를 정의해서는 않된다. ir은 현재 i의 별명이고 ir에 행해지는 것은 역으로 i에 행해진다. ir = 10; // i의 값이 10이 된다.
#include #include #include void main(){ void *vp; int i = 20; int & ir = i; clrscr(); cout << ir << endl; ir=10; cout << i << endl; i=50; cout << ir << endl; getch(); } 레퍼런스는 함수간 매개변수 전달 시 강력한 힘을 발휘한다. int i=10; const int *ip = &i; ip는 const int에 대한 포인트이다. 그러므로 ip의 내용은 수정할 수가 없다. 아래의 예제를 보자.
#include #include #include void main(){ int i = 20; const int * ip= &i ; clrscr(); cout << *ip << endl; *ip=10; // 에러발생 (cannot modify a const object) cout << *ip << endl; getch(); } 상수 포인트는 일반변수를 상수처럼 다루도록 요구하여 접근을 제한할 때 사용한다. int i = 20; int * const ip = &i; ip 가 const형임을 의미한다. 즉 ip를 바꿀 수 없다. 그러나 ip의 내용은 바꿀 수 있다.
#include #include #include void main(){ int i = 20, j =10 ; int * const ip= &i ; clrscr(); cout << *ip << endl; *ip=j; // ip의 내용은 바꿀 수 있다. cout << *ip << endl; ip = &j; // 에러발생 (cannot modify a const object) getch(); } int i = 25; const int & r = i; r은 상수에 대한 레퍼런스이다. 따라서 r로써 i의 값을 변경할 수 었다. r=30; // 에러 발생 하지만 i에 직접 값을 바꿀 수는 있다. i=30; r은 읽기 전용이다.
동적(dynamic)이란 말은 변화를 의미하는데, 동적 메모리 할당(dynamic memory allocation)은 메모리를 할당하고 해제할 때 힙의 크기가 변하는 것을 말한다.
힙은 남겨진 메모리이다. 힙에 정수를 하나 할당하자. int * a = new int; new라는 키워드는 힙을 사용하라는 의미이다. 힙에 int 만큼 메모리를 잡아서 변수 a가 가리키도록 한다. 물론 하나의 변수를 힙에 할당하는 것은 그렇게 좋은 것은 아니다. 다음과 같이 보통 배열을 할당할 때 사용한다. int *a = new int[100];
#include #include #include void main(){ int *arr = new int[10]; // 메모리 할당 clrscr(); for(int i = 0; i < 10; i++){ //초기화 *(arr+i) = i*2; } for(i = 0; i < 10; i++){ // 출력 cout << *(arr+i) << endl; } getch(); } new로 메모리를 할당하면 delete으로 해제한다. 메모리를 반납하여 다른 자원이 이 메모리를 쓸 수 있도록 한다. delete a; // 메모리를 힙에 돌려줌 다음 문장은 new로 할당된 메모리의 배열을 해제한다. delete [] arr; // 힙으로부터 배열을 해제한다.
#include #include #include void main(){ int *arr=new int[10]; clrscr(); for(int i=0;i<10;i++){ *(arr+i)=i*2; } for(i=0;i<10;i++){ cout << *(arr+i)< } delete [] arr; // 메모리 해제 getch(); } detete arr; 으로 하면 배열의 첫 번째 요소만 해제하므로 주의해야 한다. int (*arr) [6] = new int[5][6]; // (* arr) arr이 포인트라는 것이다. int (*arr2)[5][6]= new int[4][5][6]; 첫 번째 차원은 명시하지 않으며 두 번째 차원은 배열의 첫 번째 차원의 각 요소들을 위해 6개의 요소를 갖는다. delete [] arr; // []가 하나 뿐임을 주시하자. delete [] arr2; 메모리를 해제한다.
#include #include #include void main(){ int (*arr)[6] = new int[5][6]; // 할당 clrscr(); for(int i = 0;i < 5;i++) // 초기화 for(int j = 0;j < 6;j++) *(*(arr + i) + j) = i + j; for(i = 0;i < 5;i++){ // 출력 for(j = 0;j < 6;j++) cout << setw(5) << arr[i][j]; cout << endl; } delete [] arr; // 해제 getch(); } |