1] Remind C
1. const의 의미
const int num = 10; // 변수 num을 상수화
const int* ptr1 = &val1; // ptr1을 이용해서 val1의 값을 변경할 수 없음
int* const ptr2 = &val2; // ptr2를 상수화
2. 메모리 영역
- 데이터 영역: 전역변수가 저장되는 영역
- 스택: 지역변수 및 매개변수가 저장되는 영역
- 힙: malloc 함수 호출에 의해 프로그램이 실행되는 과정에서 동적으로 할당이 이뤄지는 영역.
- malloc & free : malloc 함수호출에 의해 할당된 메모리 공간은 free 함수호출을 통해서 소멸되지 않으면 해제되지 않는다.
2] bool
: true와 false는 1과 0이 아니다.
cout<<"true : "<<true<<endl;
cout<<"false : "<<false<<endl;
->
true : 1
false : 0
위 결과는 보고 true는 1, false는 0 이라고 생각할 수도 있다.
cout<<"sizeof 1: "<<sizeof(1)<<endl;
cout<<"sizeof 0: "<<sizeof(0)<<endl;
cout<<"sizeof true: "<<sizeof(true)<<endl;
cout<<"sizeof false: "<<sizeof(false)<<endl;
->
sizeof 1 : 4
sizeof 0 : 4
sizeof true : 1
sizeof false : 1
위 결과를 보면 true, false의 크기와 0, 1의 크기가 다르다.
true와 false가 정의되기 전에는 참과 거짓을 표현하기 위해서 1, 0으르 사용했기 때문에 이 둘을 출력하거나 정수의 형태로 형 변환하는 경우에 각각 1과 0으로 변환되도록 정의되어 있을 뿐이다.
따라서 true와 false는 참과 거짓을 나타내는 목적으로 정의도니 데이터로 인식하는 것이 바람직하다.
3] reference의 이해
: 할당된 하나의 메모리 공간에 다른 이름을 부여하는 것이다.
int &num2=num1;
위에서 "&"는 주소값을 반환하는 연산자가 아니라, 참조자의 선언을 뜻한다.
int num1 = 1020;
int &num2 = num1;
num2 = 3047;
위 코드를 실행하면 num1, num2 모두 3047을 가진다. 이 결과는 하나의 메모리 공간을 똑같이 가리키니까 어찌보면 당연한 결과다.
1) 참조자(reference)를 이용한 Call-by-reference
void SwapByRef(int &ref1, int &ref2)
{
int temp=ref1;
ref1=ref2;
ref2=temp;
}
2) 참조자(reference)를 이용한 Call-by-reference, 그리고 const 참조자
: 지금까지만 보면, 포인터를 이용한 Call-by-reference 보다 reference를 이용한 것이 더 간단하고 편해보인다. 하지만 단점이 있다.
int num=24;
HappyFunc(num);
위 코드에서 num의 값은 HappyFunc 함수 호출이후 어떤값이 될까? C라면 100프로 24가 되야 하지만, C++ 에서는 알수가 없다. reference를 이용한 Call-by-reference일 수도 있기 때문이다.
이런 단점을 극복하려면 const 키워드를 사용해서 상수화 시켜야 한다.
void HappyFunc(const int &ref) { ... }
위에서 ref는 함수내에서 값을 변경할 수 없다. 따라서, 함수 내에서 참조자를 통한 값의 변경을 진행하지 않은경우는 const 키워드를 사용해서 함수 원형만 봐도 값의 변형이 이뤄지지 않음을 알수있게 해라.
3) 반환형이 참조형(reference type)인 경우
int& RefRetFuncOne(int &ref)
{
ref++;
return ref;
}
int num1=1;
int &num2=RefRetFuncOne(num1);
num1++;
num2++;
cout<<"num1: "<<num1<<endl;
cout<<"num2: "<<num2<<endl;
-> 출력
num1: 4
num2: 4
그런데 위 함수의 반환값을 int형으로 받으면 어떻게 되는지 보겠다.
num1 = 1;
int num2 = RefRetFuncOne(num1);
num1+=1;
num2+=100;
cout<<"num1: "<<num1<<endl;
cout<<"num2: "<<num2<<endl;
-> 출력
num1: 3
num2: 102
int&을 int형으로 받을 수 있고 이는 완전 다른 변수가 된다.
그렇지만 int 반환값을 int&로 받을 수는 없다.
다음은 잘못된 예를 들어보겠다.
int& RetuRefFunc(int n)
{
int num = 20;
num+=n;
return num;
}
int &ref = RetuRefFunc(10);
int를 return 하지만 함수의 반환형으로 인해 int& 타입이 return 된다.
그래서 ref 변수는 num 변수의 메모리를 같이 참조하게 되지만, num은 지역변수 이기 때문에 반환되어 ref 변수는 쓰레기값을 가지게 된다.
4) 참조자(reference)의 상수 참조
: 리터럴 상수를 reference가 참조하려면 const 키워드를 사용해야 한다.
const int *ref = 30;
위와같은 코드가 과연 필요한지 의문이 들기는 하지만 굳이 사용법을 찾아보겠다.
int Adder(const int& num1, const int& num2)
{
return num1+num2;
}
위 함수에서 매개변수 둘을 더한값을 return하기 위해 변수 하나를 더 만드는것이 귀찮기 때문에 저런식으로 사용한 것이다.
4] malloc & free를 대신하는 new & delete
: malloc, free를 사용해서 heap에 메모리를 할당, 해제하는것보다 조금 더 간단해졌다.
int* ptr1 = new int; // int형 변수의 할당
double* ptr2 = new double; // double형 변수의 할당
int* arr1 = new int[3]; // 길이가 3인 int 형 배열의 할당
double * arr2 = new double[7]; //길이가 7인 double형 배열의 할당
delete ptr1;
delete ptr2;
delete []arr1;
delete []arr2;
* C++ 에서는 malloc, free 대신에 꼭 new, delete를 사용하자. 둘은 사용방식에 차이가 있어서 C++에서 malloc, free의 사용이 오류를 일으킬 수 있다.
* heap에 할당된 변수도 참조자(reference)로 접근할 수 있다.
int* ptr = new int;
int& ref = (*ptr);
ref = 20;
cout<<(*ptr)<<endl;
-> 출력
20
'C++' 카테고리의 다른 글
[C++] Friend와 Static 그리고 Const (0) | 2017.12.25 |
---|---|
[C++] 복사 생성자(Copy Constructor) (0) | 2017.12.23 |
[C++] 클래스의 완성 (1) | 2017.12.23 |
[C++] 클래스의 기본 (0) | 2017.12.23 |
[C++] C언어 기반의 C++(1) (0) | 2017.12.18 |