과제 1
https://github.com/coderrim/SWING/commit/b5bb422f5f9f16038dd9812c1ac01935fbd8b9e5
Create SWING C++ 03 -1 · coderrim/SWING@b5bb422
coderrim committed Oct 21, 2023
github.com
포인터
변수 :
일반적으로 특정한 값을 저장하는 메모리 공간의 이름을 말한다. 계속 바뀔 수 있는 값을 담는 상자와 같다.
int n;
n=2;
포인터 변수 :
변수의 주소를 저장하는 변수이다. 2 라는 값을 가진 변수 n 에 대한 포인터 p 에는 n 이 있는 메모리의 주소값이 저장된다.
n : 2
*p : 2
p : 100번지
&n : 100번지
포인터를 선언하는 방식에는 분리형과 통합형이 있다.
분리형 : 두 줄
int *p; // 앞에 * 기호를 붙여 선언한다. *p 는 포인터 p 가 가리키는 변수의 값을 말한다.
p=&n; // n 의 주소를 저장한다. &n 은 n 의 주소값이라는 뜻이다. &는 앰퍼샌드라고 읽는다.
통합형 : 한 줄
int *p=&n;
자료형마다 할당되는 메모리의 크기가 다른데, 포인터 변수에 자료형을 선언하는 이유가 여기에 있다.
포인터 변수 p 가 가리키는 변수 n 의 데이터를 읽을 때 몇 바이트를 읽을지를 p 의 자료형이 결정한다.
<정수형>
char 1 byte
short 2 byte
int 4 byte
long 4 byte
long long 8 byte
<실수형>
float 4 byte
double 8 byte
위의 내용은 포인터가 가리키는 변수의 크기, 즉 변수의 데이터를 저만큼씩 읽는다는 것이고,
이와 별개로 포인터 변수 자체의 크기는 모두 4 byte 로 같다.
배열 :
각 원소가 차지하는 메모리는 데이터 형의 크기와 같다.
int n[5]={1,2,3,4,5};
포인터와 배열은 엮여서 자주 사용되며 포인터의 장점은 배열을 가리킬 때 두드러진다.
포인터 변수가 배열을 가리키면 주소를 어떻게 저장할까?
int *p=NULL;
p=n; 또는 p=&n[0];
둘다 포인터 변수에는 해당 배열의 첫 번째 원소의 주소가 저장된다.
포인터 p가 배열의 주소를 저장하려면,
선언할 때 포인터가 배열명 자체(n) 혹은 배열의 첫 번째 주소(&n[0])를 가리키도록 해야한다.
위의 배열 n[5] 를 포인터 p 가 가리킨다고 해보자.
*p : n[0] == 1
*(p+1) : n[1]
*(p+a) : n[a] == a+1
포인터 변수 자체에 +1 을 하면 변수의 주소값은 자료형의 크기만큼 더해진다.
*p+1= int a+1
p+1=&a+4
참조
참조 (reference) 란, 이미 존재하는 변수에 대한 별명으로, 가리킨다는 뜻이다.
별명만 생기고 메모리에 새로운 공간이 할당되진 않는다.
함수 호출에 유용하다.
int n=2;
int &ref=n;
이렇게 ref 를 변수 n에 대한 참조자로 선언하고나면,
cout << ref; // n 의 값인 2가 출력된다.
int *p=&ref; // 포인터를 선언할 때 변수 n 대신 사용 가능
포인터 | 참조자 |
메모리에 공간을 할당해 포인트라는 변수를 새로 만든다. 초기화 전 선언도 NULL 초기화도 가능하다. |
별도의 메모리 공간이 할당되지 않는다. 선언과 동시에 NULL이 아닌 값으로 초기화 해야한다. 단독으로 존재할 수 없는 별명이라, 빈 공간이면 존재할 이유가 없다. |
주소값으로 데이터에 접근해 내용을 변경할 수 있다. *p=2; 이런 식으로. |
별명에 불과해서 가리키는 변수 내부의 값을 변경할 수 없다. |
숫자만 바꾸면 배열 구조 내 다른 인덱스의 메모리에 접근 가능하다. |
메모리 주소에 접근이 불가능해서 안전하다. |
함수의 인자 전달 방식
int function(int a, int b) {
int c=a+b;
return c;
}
int main(){
int sum=function(2,3);
cout << sum;
}
이런 식으로 main 함수에서 function(2,3) 을 통해 function 함수를 호출할 수 있다.
2 와 3 은 인자로써 function 함수에 값을 넣어준다.
a 와 b 는 매개변수로써 인자의 값을 받아들인다.
이때 함수에 인자를 전달하는 세 가지 방법이 있다.
Call by value
1. swap 함수를 호출 -> 인자 m, n 의 값 -> 매개 변수 a, b 로 복사
2. swap 함수 내부 과정 수행 ( 지역변수 a 와 b 교환 )
3. swap 함수 호출 후 main 함수 m, n 출력
( m, n 값 그대로 )
함수의 매개 변수 타입 : 일반 변수
함수 호출 시 매개 변수로 넘겨주는 것 : 기존 변수의 값
함수 호출 이후에 인자를 넘겨준 기존 변수에 저장된 값 변경 여부 : 변하지 않음
Call by address
1. swap 함수를 호출 -> 인자 m, n 의 값 -> 매개 변수 a, b 로 복사
2. int* a=&m, int* b=&n -> a, b 포인트 변수로 선언
3. swap 함수 호출 후 main 함수 m, n 출력
( m, n 값이 바뀜. a, b 가 주소값을 담은 포인트 변수로써 원래 변수에 저장된 값을 제어하는게 가능하기 때문임. )
함수의 매개 변수 타입 : 포인터
함수 호출 시 매개 변수로 넘겨주는 것 : 변수 주소값
함수 호출 이후에 인자를 넘겨준 기존 변수에 저장된 값 변경 여부 : 변함
Call by reference
1. swap 함수를 호출 -> 인자 m, n 의 값 -> 매개 변수 a, b 로 복사
2. int& a=m, int& b=n -> a, b 가 m, n 의 참조자가 됨
3. swap 함수 호출 후 main 함수 m, n 출력
( m, n 값이 바뀜. swap 함수를 실행하면서 참조자 a, b 가 교환될 때 원래 변수인 m, n 도 교환되었기 때문임. )
함수의 매개 변수 타입 : 참조자
함수 호출 시 매개 변수로 넘겨주는 것 : 기존 변수의 값
함수 호출 이후에 인자를 넘겨준 기존 변수에 저장된 값 변경 여부 : 변함
inline 함수
inline function 는 정의한 코드들이 인라인 함수를 호출하면 코드 자체가 안으로 들어가는 것으로,
프로그램의 실행 속도를 빨라지게 한다.
하지만 인라인 함수가 길거나 여러 번 호출하면 파일을 크게 만들어 메모리를 많이 사용한다는 단점이 있다.
내부 루프가 없는 짧은 함수에 적합하다.
1. 컴파일러에서 함수를 인라인 함수로 처리하도록 요청
2. 모든 인라인 함수가 인-플레이스 확장
3. 함수 호출이 인라인 함수 자체의 내용 복사본으로 대체
4. 함수 오버헤드 (overhead. 함수 내용이 아닌 함수를 호출하는데 들어가는 불필요한 비용) 제거
inline void Print() {
cout << "Hello, World" << endl;
}
int main() {
Print();
return 0;
}
int main() {
cout << "Hello, World" << endl;
return 0;
}
두 코드의 실행 결과는 같다.
과제 2
자산 관리 서비스 프로그램
https://github.com/coderrim/SWING/commit/b38cf78fe90db750e85e21ffe6d9ba8895f9a7a9
Create SWING C++ 03 -2 · coderrim/SWING@b38cf78
coderrim committed Oct 21, 2023
github.com
'C++' 카테고리의 다른 글
[SWING] C++ 06 (0) | 2022.06.27 |
---|---|
[SWING] C++ 05 (0) | 2022.05.23 |
[SWING] C++ 04 (0) | 2022.05.14 |
[SWING] C++ 02 (0) | 2022.05.01 |
[SWING] C++ 01 (0) | 2022.03.27 |