9. [C++] 참조자(Reference)와 함수
2024. 4. 11. 15:55ㆍ[C++]/C++ 언어 기초
🍃 Call-by-value & Call-by-reference
Call-by-value 값을 인자로 전달하는 함수의 호출방식
Call-by-reference 주소 값을 인자로 전달하는 함수의 호출방식
이 중, Call-by-value 기반의 함수는 다음과 같이 정의된 함수를 의미한다.
int Adder(int num1, int num2) {
return num1 + num2;
}
- 위 함수는 두 개의 정수를 인자로 요구하고 있다.
- Call-by-value 형태로 정의된 함수의 내부에서는, 함수외부에 선언된 변수에 접근이 불가능하다.
- 따라서 두 변수에 저장된 값을 서로 바꿔서 저장할 목적으로 다음과 같이 함수를 정의하면 원하는 결과를 얻을 수 없다.
Call-by-value 기반의 함수
void SwapByValue(int num1, int num2) {
int temp = num1;
num1 = num2;
num2 = temp;
}
위의 함수를 대상으로 다음의 main 함수를 실행하면, 출력결과는 다음과 같다.
int main(void) {
int val1 = 10;
int val2 = 20;
SwapByValue(val1, val2);
//val1과 val2에 저장된 값이 바뀌기를 기대함
cout<<"val1: "<<val1<<endl; // 10 출력
cout<<"val2: "<<val2<<endl; // 20 출력
return 0;
}
val1 = 10
val2 = 20
- 이는 val1과 val2에 저장된 값이 서로 바뀌지 않았음을 의미한다.
- 그래서 필요한 것이 Call-by-reference 기반의 함수이다.
Call-by-reference 기반의 함수
void SwapByRef(int * ptr1, int * ptr2) {
int temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
}
위의 함수에서는 두 개의 주소 값을 받아서 주소 값이 참조하는 영역에 저장된 값을 직접 변경하고 있다. 다음의 출력결과를 확인할 수 있다
int main(void) {
int val1 = 10;
int val2 = 20;
SwapByRef(&val1, &val2);
//val1과 val2에 저장된 값이 바뀌기를 기대함
cout<<"val1: "<<val1<<endl; // 20 출력
cout<<"val2: "<<val2<<endl; // 10 출력
return 0;
}
val1 = 20
val2 = 10
🍃 Call-by-address? & Call-by-reference!
본래 C언어에서 말하는 Call-by-reference는 다음의 의미를 지닌다.
"주소 값을 전달받아서, 함수 외부에 선언된 변수에 접근하는 형태의 함수호출"
C++에서는 함수 외부에 선언된 변수의 접근 방법으로 두 가지가 존재한다.
하나는 '주소 값'을 이용하는 방식, 다른 하나는 ' 참조자'를 이용하는 방식이다.
- 주소값을 이용한 Call-by-reference
- 참조자를 이용한 Call-by-reference
이렇듯 C++에서는 두 가지 방식으로 Call-by-reference의 함수정의가 가능하다.
🍃 참조자를 이용한 Call-by-reference
- C++에서는 참조자를 기반으로도 Call-by-reference의 함수호출을 진행할 수 있다.
- Call-by-reference의 가장 큰 핵심은 함수 내에서 함수외부에 선언된 변수에 접근할 수 있다는 것이다.
void SwapByRef2(int &ref1, int &ref2) {
int temp = ref1;
ref1 = ref2;
ref2 = temp;
}
참조자는 선언과 동시에 변수로 초기화되어야 한다면서요!
- 매개변수는 함수가 호출되어야 초기화가 진행되는 변수들이다.
- 즉, 위의 매개변수 선언은 초기화가 이뤄지지 않은 것이 아닌, 함수 호출 시 전달되는 인자로 초기화를 하겠다는 의미이다.
int main(void) {
int val1 = 10;
int val2 = 20;
SwapByRef2(val1, val2);
cout<<"val1: " <<val1<<endl;
cout<<"val2: " <<val2<<endl;
return 0;
}
- 매개변수로 선언된 참조자 ref1과 ref2는 main 함수에서 선언된 변수 val1과 val2의 다른 이름이 된다.
- 그리고 SwapByRef2 함수 내에서는 이 두 참조자를 통해 값의 교환 과정을 거친다.
RefSwap.cpp
#include <iostream>
using namespace std;
void SwapByRef2(int &ref1, int &ref2) {
int temp =ref1;
ref1=ref2;
ref2=temp;
}
int main(void) {
int val1 = 10;
int val2 = 20;
SwapByRef2(val1, val2);
cout<<"val1: "<<val1<<endl;
cout<<"val2: "<<val2<<endl;
return 0;
}
val1: 20
val2: 10
문제 풀이
문제 1
참조자를 이용해서 다음 요구사항에 부합하는 함수를 각각 정의하여라.
-> 인자로 전달된 int형 변수의 값을 1씩 증가시키는 함수
-> 인자로 전달된 int형 변수의 부호를 바꾸는 함수
그리고 위의 각 함수를 호출하여 그 결과를 확인하는 main 함수까지 작성하여라.
내 풀이
#include "stdafx.h"
#include <iostream>
#include <cstring>
using namespace std;
using namespace System;
void increseNum(int *num1, int *num2)
{
*num1 += 1;
*num2 += 1;
}
void reverseNum(int *num1, int *num2){
*num1 *= -1;
*num2 *= -1;
}
int main(array<System::String ^> ^args)
{
int num1,num2;
cout<<"숫자1 입력 : "; cin>>num1;
cout<<"숫자2 입력 : "; cin>>num2;
cout<<"[입력한 숫자]"<<endl<<"숫자1 : "<<num1<<endl<<"숫자2 : "<<num2<<endl;
increseNum(&num1, &num2);
cout<<"[1 증가한 숫자]"<<endl<<"숫자1 : "<<num1<<endl<<"숫자2 : "<<num2<<endl;
reverseNum(&num1, &num2);
cout<<"[부호 바뀐 숫자]"<<endl<<"숫자1 : "<<num1<<endl<<"숫자2 : "<<num2<<endl;
}
문제 2
앞서 소개한 예제 RefSwap.cpp의 SwapByRef2 함수를 다음의 형태로 호출하면 컴파일 에러가 발생한다.
SwapByRef2(23, 45);
컴파일 에러가 발생하는 이유가 무엇인지 설명해보자.
내 풀이
- SwapByRef 함수의 매개변수 선언 위치에 참조자가 선언되었다.
- 참조자는 상수를 참조할 수 없기 떄문에 매개변수의 인자로는 반드시 변수가 등장해야한다.
- SwapByRef2(23, 45)는 상수로 호출하기 때문에 컴파일 에러가 발생한다.
문제 3
문제의 제시에 앞서 먼저 다음 코드를 보자.
int main(void) {
int num1 = 5;
int ptr1 = &num1;
int num2 = 10;
int ptr2 = &num2;
. . . .
}
위의 코드를 보면 ptr1과 ptr2가 각각 num1과 num2를 가리키고 있다. 이 때 ptr1과 ptr2를 대상으로 다음과 같이 함수를 호출하고 나면,
SwapPointer(ptr1, ptr2);
ptr1과 ptr2가 가리키는 대상이 서로 바뀌도록 SwapPointer 함수를 정의해보자.
내 풀이
#include "stdafx.h"
#include <iostream>
#include <cstring>
using namespace std;
using namespace System;
void SwapPointer(int *ptr1, int *ptr2){
int temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
}
int main(array<System::String ^> ^args)
{
int num1 = 5;
int *ptr1 = &num1;
int num2 = 10;
int *ptr2 = &num2;
SwapPointer(ptr1, ptr2);
cout<<"값 : "<<*ptr1<<" "<<*ptr2<<endl;
}
반응형
'[C++] > C++ 언어 기초' 카테고리의 다른 글
11. [C++] malloc & free를 대신하는 new & delete (0) | 2024.04.11 |
---|---|
10. [C++] 참조자(Reference)와 함수2 (0) | 2024.04.11 |
8. [C++] 참조자(Reference)의 이해 (0) | 2024.04.11 |
7. [C++] 새로운 자료형 bool (0) | 2024.04.11 |
6. const, 메모리 공간, Call-by-value & Call-by-reference (0) | 2024.04.11 |