[열혈 C++ 프로그래밍] (2) C언어 기반 C++ 2
C언어 기반 C++ 2
- C언어 기반 C++
- bool 자료형
- 참조자의 이해
- 참조자와 함수
- malloc & free를 대신하는 new
C언어 기반 C++
const
변수, 객체의 상수화 키워드
const int* ptr1 = &val
-> ptr1을 이용하여 val1의 값을 변경 할 수 없음
- const 변수는 반드시 선언과 동시에 초기화
-> 멤버 변수를 const로 선언하는 경우에는 반드시
초기화 리스트(initialize list) 사용
-> Bar의 num은 초기화가 아닌 const int num;
을 선언 한 이후 num = 1;을 시도하는 것
- const 포인터
-> const가 맨 앞에 있으면서 포인터 변수가 가리키
는 값을 상수화를 하는 경우에는 *ptr 상수화
-> const 위치가 자료형과 이름 사이에 있으면 포인
터 변수 자체인 ptr을 상수화
- 멤버함수를 const로 선언하는 경우
- 멤버함수를 const로 선언하는 경우
-> 해당 멤버 함수 내의 모든 멤버 변수를 상수화
-> 멤버변수 num은 변경 불가
-> 지역변수 a는 변경 가능
메모리 공간
- 데이터 영역 : 전역변수 저장 +프로그램 실행부터 끝까지 사용되는 메모리
- 스택 영역 : 지역변수 저장 + 프로그램 실행과정에서 필요한 메모리(함수 호출 등)
- 힙 영역 : 할당과 해제를 통해 생성/소멸 되는 메모리
call by value
값에 의한 호출
- 외부에서 내부 메모리 접근 및 변경 불가
call by reference
참조에 의한 호출
- 주소값을 통한 접근으로 포인터 특성 상 외부 메모리의 접근 및 변경 가능
- 참조에 의한 호출
인자를 넘겨주는 경우 매개변수 만큼의 메모리의 재할
당이 일어남
-> 참조를 통해 메모리 재할당 없이 메모리에 접근
bool 자료형
참/거짓을 나타내는 자료형 -> true&false
참조자의 이해
기존에 선언된 변수에 할당된 메모리 공간에 새롭게 접근 할 수 있는 방법
- 기존에 선언된 변수에 &를 붙이면 단순 주소값 반환 <-> 새롭게 선언되는 변수에 &를 붙이면 참조 연산자
- 참조 연산자는 기존 선언된 변수에 붙는 별칭 <-> 기존 변수명과 동일한 역할
- 새로운 메모리 공간이 할당되는 것이 아닌 기존에 할당된 메모리 공간에 접근 하는 것
- 참조자를 대상으로 참조자 선언 가능
+ 참조자는 생성과 동시에 참조 (int &ref; -> X)
+ null로 초기화 불가능
+ 참조하는 대상을 변경하는 것은 불가능
+ 배열과 같이 변수의 성향을 지니는 대상은 참조자 선언이 가능
상수를 대상으로 선언 불가능 <-> const형으로는 상수를 대상으로 참조 가능
const int &ref=30;
-> 상수를 메모리에 일시적으로 저장하기 때문에 리터럴 상수라도 다음 행에서 소멸되지 않음
+ 매개변수형이 const 참조자인 경우 상수를 전달 할 수 있게 하기 위함 <-> const가 아니라면 변수
int Func(const int &num1, const int &num2) { return num1+num2; }
참조자를 사용하여 포인터를 사용하지 않고 힙 영역에 접근 가능
int main() {
int *ptr = new int;
int &ref = *ptr;
ref = 20;
cout << *ptr << endl;
cout << ptr << endl;
}
-> ptr 포인터 변수에 int형 메모리 공간을 할당
-> ptr 포인터가 가리키는 메모리 공을 ref 변수로 참조
-> ptr과 ref에게 할당된 동일 메모리 공간에 20이라는 값을 대입
-> *ptr 출력 시 메모리 공간 내 20이라는 값 출력
-> ptr 출력 시 메모리 공간의 주소값 출력
참조자와 함수
매개변수는 함수가 호출될 때 인자가 전달되면서 초기화
-> 참조자는 초기화가 필수, 매개변수로 참조자가 사용되면 호출되는 과정에서 초기화
-> 호출된 함수 내에서만 참조자가 사용되고 함수를 빠져나와 메인스택에서는 기존 변수명으로 사용
+ 함수의 정의 형태와 호출 형태를 통해서 원본의 형태를 알 수 없고 함수 몸체의 매개변수를 확인해야 함
+ 함수 내부에서 참조자를 통한 값의 변경이 이루어질 수 있기 때문에, 변경이 이루어지지 않는다면 const
void Func(const int &ref)
-> 참조자를 통한 변경이 이루어지지 않음을 판단 할 수 있음
참조자 반환형
1. 참조자로 참조형 반환값을 받는 경우
int& Func1(int &ref1) {
ref1 ++;
return ref1;
}
int main() {
int val1 = 1;
int &val2 = Func1(val1);
val1++;
val2++;
return 0;
}
-> 1이라는 값이 들어가 있는 val1이라는 메모리 공간 할당
-> val1메모리 공간에 ref1이라는 별칭 생성
-> 참조형 반환값을 참조자로 받아서 val2라는 별칭이 추가 생성
-> 매개변수로 선언된 참조자는 지역변수와 동일한 성격이기에 반환과 동시에 ref1은 소멸
-> val1과 val2는 같은 메모리 공간을 가리키기 때문에 같은 공간에 대해 연산을 진행
2. 변수로 참조형 반환값을 받는 경우
int& Func1(int &ref1) {
ref1 ++;
return ref1;
}
int main() {
int val1 = 1;
int val2 = Func1(val1);
val1++;
val2++;
return 0;
}
-> 1이라는 값이 들어가 있는 val1이라는 메모리 공간 할당
-> val1메모리 공간에 ref1이라는 별칭 생성
-> 변수 val2는 새로운 공간을 할당받아 ref1의 값을 복사하여 생성
-> ref1 소멸
-> val1과 val2는 다른 메모리 공간을 가리키기 때문에 각각의 공간에 대해 연산을 진행
3. 반환형이 기본자료형으로 선언된 함수
반환 값은 반드시 변수로 받아야 함
-> 기본 자료형으로 반환 시 이는 상수와 동일, 참조자는 변수에 대해서만 참조가 가능하다는 규칙
- 반환형이 기본 자료형, 매개변수가 참조자
-> num1이라는 메모리 공간을 매개변수 arg가 참조
-> int형으로 반환하여 num2라는 새로운 메모리 공간할당
-> num2와 num1의 메모리 공간이 별도로 존재
- 반환형이 참조자, 매개변수도 참조자
-> num1이라는 메모리 공간을 매개변수 arg가 참조
-> int 참조형으로 반환하여 num2에 반환
-> num2와 num1은 같은 메모리 공간을 가리킴
malloc & free를 대신하는 new & delete
new 연산자
메모리 공간의 동적 할당 연산
+ 자료형에 맞는 포인터를 반환 <-> malloc : 자료형이 결정되지 않은 void 포인터 반환
int* arr = new int[3];
-> int형 포인터 arr에 int형 메모리 공간을 할당
변수가 실제로 사용되지 않으면 낭비되는 메모리가 발생
-> 고정 배열을 포함한 대부분 일반 변수는 스택 메모리에 저장
-> 일반적으로 스택은 1MB~2MB 설정
-> 이 크기를 초과하면 스택 오버플로 발생
- 동적 할당은 스택 영역이 아닌 힙 영역의 메모리 풀에 할당
delete 연산자
new로 동적할당 생성된 메모리 공간을 소멸시키는 연산
delete []arr;
댕글링 포인터
: 할당이 해제된 메모리를 가리키는 포인터
-> 댕글링 포인터를 역참조하면 정의되지 않은 동작
C++에서 C언어 표준 함수 호출
C : #include<stdio.h> / #include<string.h> / #include<math.h>
C++ : #include<cstdio> / #include<cstring> / #include<츰소>
-> c를 붙이고 .h를 제외시키는 규칙성