[ 5주차 - 2 ]
const 접근자
1. const로 선언된 변수는 프로그램의 실행동안 값 변경이 불가능하며, 초기값만 줄 수 있다.
ex) const double version = 3.2;
2. 용도
- const 포인터 매개변수 생성 → 매개변수가 가리키는 대상이 함수에 의해 수정되는 것을 방지
- 참조 매개변수에 사용 → 함수에서 참조 매개변수가 참조하는 변수를 수정하는 것을 방지
- 이름을 갖는 상수 생성
ⓐ const 포인터 매개변수 생성
#include <iostream>
using namespace std;
void code(const char *str);
int main() {
code("this is a test");
return 0;
}
//const 사용은 str이 가리키는 인수를 수정할 수 없다는 것을 보장한다.
void code(const char *str) {
while (*str) { // str의 문자가 null이 아니라면 반복
cout << (char)(*str);
str++;
}
}
// ▶ this is a test
str문자에 +1을 한다는 것은 바로 다음 문자를 의미한다. *str은 str이 나타내는 문자를 가르키고 읽어온다.
void code(const char *str) {
while (*str) {
*str = *str + 1; // 에러 -> 인수를 수정할 수 없다.
cout << (char)*str;
str++;
}
}
ⓑ 참조 매개변수
#include <iostream>
using namespace std;
void f(const int &i);
int main() {
int k = 10;
f(k);
return 0;
}
//const 참조 매개변수를 사용
void f(const int &i) {
i = 100; //에러 -> const 참조를 수정할 수 없다.
cout << i;
}
const 키워드로 인해서 i가 나타내는 인수에다가 다른 값을 저장할 수 없다.
기억 공간 종류 지정자
1. auto : 지역 변수 선언, 디폴트 지정자이므로 생략 가능
2. extern : 다른 파일에 잇는 전역 변수를 선언
3. register : CPU의 레지스터에 저장한다. → 가능한 한 빠르게 접근할 수 있다.
4. static : 자신의 함수 또는 파일에서 영구적인 변수
→ 함수 외부에 알려지지 않는다는 점이 전역변수와 다르다.
static은 함수가 실행되고 종료되더라도, static 변수는 계속 살아있고, 다음 번에 함수가 또 실행되더라도
static 지역 변수는 계속 살아있어서 이전에 호출됐을 때의 값을 유지한다.
static 변수는 전역 변수처럼 사용은 가능하지만 static이라고 선언된 함수밖에서는 사용이 불가능하다.
static 변수
1. static 지역변수
- 변수를 위한 영구적인 기억 공간이 전역 변수를 위한 기억 공간과 같은 방법으로 할당함으로써 static 변수가
함수 호출들 사이에서 값을 유지할 수 있게 해준다.
- 함수가 복귀할 때 소멸되지 않는다.
→ 이전에 호출됐을 때의 값을 유지하기 때문에 두번째 호출에서도 그 값을 사용할 수 있다.
- static 지역변수는 다소 제한된 범위를 가진 전역 변수로 볼 수 있다.
- 프로그램 실행이 시작할 때 단 한번 초기화 된다.
2. static 전역변수
- 선언된 파일에서만 알려지는 전역변수를 생성한다.
ex) 사용자가 수를 입력할 때마다 현재까지의 평균을 출력하기
#include <iostream>
using namespace std;
int r_avg(int i);
int main() {
int num;
do {
cout << "Enter numbers ( -1 : exit ) : ";
cin >> num;
if (num != -1) {
cout << "Running average is : " << r_avg(num) <<"\n";
}
} while (num > -1);
return 0;
}
int r_avg(int i) {
static int sum = 0, count = 0;
sum += i;
count++;
return sum / count;
}
// ▶ Enter numbers ( -1 : exit ) : 10
// Running average is : 10
// Enter numbers ( -1 : exit ) : 20
// Running average is : 15
// Enter numbers ( -1 : exit ) : 30
// Running average is : 20
// Enter numbers ( -1 : exit ) : -1
비트 연산자
& | AND |
| | OR |
^ | XOR |
~ | NOT |
>> | 오른쪽 시프트 |
<< | 왼쪽 시프트 |
#include <iostream>
using namespace std;
void disp_binary(unsigned u);
int main() {
int i = 1, j;
for ( j = 0; j < 8; j++) {
disp_binary(i); //u는 unsigned int이기 때문에 4byte
i = i << 1;
}
cout << "\n";
for ( j = 0; j < 8; j++) {
i = i >> 1;
disp_binary(i);
}
return 0;
}
// 바이트 내의 비트들을 출력한다.
void disp_binary(unsigned u) {
register int t;
for (t = 128; t > 0; t = t / 2) { //8비트씩(한줄) 반복
if (u & t) { //u와 t가 0인지 1인지 &를 시켜서 참이면 1이고 거짓이면 0
cout << "1 ";
}
else {
cout << "0 ";
}
}
cout << "\n";
}
// ▶ 0 0 0 0 0 0 0 1
// 0 0 0 0 0 0 1 0
// 0 0 0 0 0 1 0 0
// 0 0 0 0 1 0 0 0
// 0 0 0 1 0 0 0 0
// 0 0 1 0 0 0 0 0
// 0 1 0 0 0 0 0 0
// 1 0 0 0 0 0 0 0
// 1 0 0 0 0 0 0 0
// 0 1 0 0 0 0 0 0
// 0 0 1 0 0 0 0 0
// 0 0 0 1 0 0 0 0
// 0 0 0 0 1 0 0 0
// 0 0 0 0 0 1 0 0
// 0 0 0 0 0 0 1 0
// 0 0 0 0 0 0 0 1
복합 치환문 ( compound assignment )
복합 치환문 : 다른 연산을 치환문과 결합한 형태의 치환문
복합 치환문 연산자는 C++에 있는 모든 이항 연산자들과 함꼐 사용 가능 ex) +=, -=
콤마 연산자
콤마 연산자 : 여러 개의 식을 함께 묶는 것
콤마로 분리된 식들의 리스트이 값은 맨 오른쪽에 있는 식의 값으로 다른 식들의 값을 버린다.
var = ( count=10, incr=10, count+1 ); // var=20
#include <iostream>
using namespace std;
int main() {
int i, j;
j = 10;
i = (j++, j + 100, 999 + j);
cout << i;
return 0;
}
// ▶ 1010
다중 치환문
많은 변수들에게 같은 값을 치환하는 편리한 방법
count = incr = index = 10;
sizeof 사용하기
sizeof : 어떤 자료형의 크기를 바이트 수로 알려준다.
sizeof( type )
sizeof( value )
new와 delete를 사용하는 동적 할당
C++ 프로그램이 정보를 컴퓨터의 메인 메모리에 저장하는데 사용하는 두가지 방법
1. 변수들을 사용 : 컴파일 시간에 고정되어, 프로그램의 실행 동안에 변경될 수 있다.
2. C++의 동적 할당 시스템 사용
- heap를 사용하여 필요한 만큼의 공간을 할당한다.
- heap의 영역이 충분치 않다면 예외 발생
- 동적으로 할당되는 기억 공간은 실행 시에 얻는다.
pointer_var = new var_type;
delete pointer_var;
#include <iostream>
using namespace std;
int main() {
int *p;
p = new int; // new를 사용해서 int를 위한 메모리를 할당
*p = 20; // 그 메모리에 20을 치환
cout << *p;
delete p; // 메모리를 해제
return 0;
}
p는 포인터 변수이고 p에는 int 크기의 메모리가 동적 할당이 되서 이 동적 할당된 메모리의 주소가 p에 저장이 된다.
→ p에는 동적 할당된 메모리의 주소가 저장이 되어 있다.
p는 포인터 변수이므로 주소를 저장할 수 있는데 new를 사용해서 새로 할당된 메모리의 주소가 저장되는 것이다.
*p에 20을 넣어주면 p에 저장되는 것이 아니라 p가 가리키고 있는 메모리에 20이 저장된다.
delete p라 하면 p가 사라지는 것이 아니라, p가 가리키고 있는 새로 동적 할당된 메모리가 사라진다.
3. 배열 할당
pointer_var = new type[size];
delete []inter_var;
#include <iostream>
using namespace std;
int main() {
double *p;
p = new double[10]; //10개의 원소의 배열을 할당
for (int i = 0; i < 10; i++) {
p[i] = 100.00 + i;
}
for (int j = 0; j < 10; j++) {
cout << p[j] << " ";
}
delete []p; // 배열 해제
return 0;
}
p 포인터 변수를 선언하고 10 크기의 배열을 동적할당한다. 동적 배열을 할당할 때 크기에 상수값을 줘야할
필요는 없다. cin을 통해 배열의 크기를 입력받을 수 있고 그 값을 동적 배열의 크기로 할당해 생성할 수 있다.
실습문제
1. 하나의 정수를 입력받아 그 수의 크기만큼 배열을 동적으로 생성
2. 그 수 만큼의 정수를 입력받아 배열에 저장
3. 배열의 각 원소에 대해 자신보다 작은 수들의 개수를 계산하여 출력
#include <iostream>
using namespace std;
int main() {
int size;
cout << "배열 크기 입력 : ";
cin >> size;
int *myArray = new int[size]; // 배열 할당
cout << "\n배열의 입력할 값 입력 : ";
for (int i = 0; i < size; i++) {
cin >> myArray[i];
}
int max = 0;
for (int j = 0; j < size; j++) {
int count = 0;
max = myArray[j];
for (int k = 0; k < size; k++) {
if (max > myArray[k]) {
count++;
}
}
cout << myArray[j] << "보다 작은 원소 갯수 : " << count << "\n";
}
delete []myArray; // 배열 해제
return 0;
}
'2CHAECHAE 학교생활 > 객체지향프로그래밍(C++)' 카테고리의 다른 글
[ 객체지향프로그래밍(C++) 6주차 ② ] (0) | 2022.04.11 |
---|---|
[ 객체지향프로그래밍(C++) 6주차 ① ] (0) | 2022.04.11 |
[ 객체지향프로그래밍(C++) 5주차 ① ] (0) | 2022.04.01 |
[ 객체지향프로그래밍(C++) 4주차 ② ] (0) | 2022.03.28 |
[ 객체지향프로그래밍(C++) 4주차 ① ] (0) | 2022.03.24 |