1. C++에서 함수 호출 시 인자를 넘겨줄 수 있는 방법들을 알아보겠습니다.
2. 포인터로 클래스의 멤버를 접근할 때 사용하는 연산자(->, .)의 차이를 정리해 보겠습니다.
값에 의한 호출?
- call by value
- 함수 호출 시 인자로 들어온 값을 복사해서 사용
- 호출된 함수에서 연산을 거쳐도 인자에 영향을 주지 않음
예)
void swap(int x, int y) // 함수 구현부
{
// 내용
}
swap(input1, input2); // 함수 호출 형태
주소에 의한 호출?
- call by address
- 새롭게 변수를 생성하고 그곳에 값을 저장하는 것이 아니므로 자원을 절약할 수 있음. (메모리, 시간)
- 함수 호출 시 주소 값을 인자로 받음
- 호출할 함수의 매개변수를 포인터 형태로 구현
- 호출된 함수에서 들어온 인자로 연산을 거치면 함수 바깥에도 영향을 줄 수 있음
예)
void swap(int *x, int *y) // 매개변수가 포인터 형태
{
// 내용
}
swap(&input1, &input2); // 주소를 인자로 넘김
int *x = &input1; 의 형태입니다.
포인터 x는 input의 주소를 저장하게 됩니다. 이후 역참조 연산자(*)를 사용하여, 포인터가 가리키는 변수 값을 접근할 수 있습니다. (*x)
참조에 의한 호출?
- call by reference
- C++에서만 사용 가능 (C는 불가)
- 함수 호출 시 인자로 들어온 값을 참조함
- 주소에 의한 호출과 비슷하지만 코드 가독성이 높아지고 실수할 위험 감소
예)
void swap(int &x, int &y) // 매개변수에 참조 연산자 사용 (주소를 받는 느낌)
{
// 내용
}
swap(input1, input2); // 값에 의한 호출과 같은 형태
->와 .?
- -> 연산자는 포인터를 통해 클래스의 멤버에 접근할 때 사용
- . 연산자는 클래스의 멤버에 직접 접근할 때 사용
- 포인터 a가 객체를 가리키고 있을 때 (*a).b와 a->b는 동일한 표현
예)
// string 클래스를 예로 들면
string str = "test";
string *pstr = &str;
cout << "*pstr : " << *pstr << endl; // test
cout << "(*pstr).size() : " << (*pstr).size() << endl; // 4
cout << "pstr->size() : " << pstr->size() << endl; // 4
- '참조에 의한 호출'을 '주소에 의한 호출'로 변환해 보면서, 클래스에 포인터를 사용할 때 헷갈리는 부분이 있더라고요. 정리할 겸 같이 넣었습니다.
전체 소스 코드 (~에 의한 호출)
#include <iostream>
using namespace std;
void swap(int x, int y) // 값에 의한 호출
{
cout << "sawp() 호출\n";
int tmp = x;
x = y;
y = tmp;
}
void swap2(int *x, int *y) // 주소에 의한 호출
{
cout << "sawp2() 호출\n";
int tmp = *x;
*x = *y;
*y = tmp;
}
void swap3(int &x, int &y) // 참조에 의한 호출
{
cout << "sawp3() 호출\n";
int tmp = x;
x = y;
y = tmp;
}
int main()
{
int input1, input2;
// 값에 의한 호출
input1 = 2, input2 = 5;
cout << input1 << " " << input2 << endl;
swap(input1, input2);
cout << input1 << " " << input2 << endl << endl;
// 주소에 의한 호출
input1 = 4, input2 = 7;
cout << input1 << " " << input2 << endl;
swap2(&input1, &input2);
cout << input1 << " " << input2 << endl << endl;
// 참조에 의한 호출
input1 = 5, input2 = 9;
cout << input1 << " " << input2 << endl;
swap3(input1, input2);
cout << input1 << " " << input2 << endl;
return 0;
}
전체 소스 코드 (포인터로 클래스 접근하기)
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "test";
string* pstr = &str;
cout << "str : " << str << endl; // test
cout << "str.size() : " << str.size() << endl; // 4
cout << "&str : " << &str << endl; // str의 주소값
cout << "pstr : " << pstr << endl; // str의 주소값
cout << "*pstr : " << *pstr << endl; // test
cout << "(*pstr).size() : " << (*pstr).size() << endl; //
cout << "pstr->size() : " << pstr->size() << endl; //
return 0;
}
참고 자료
https://codemasterkimc.tistory.com/14 - c++에서 ->와 .의 차이
https://brightwon.tistory.com/7 - call by value, address, reference
https://www.acmicpc.net/board/view/146295 - 참조에 의한 호출이 주는 자원 감소 효과
'CS > 코딩테스트(C++)' 카테고리의 다른 글
[C++ STL] Vector에서 assign과 resize 차이 (0) | 2025.01.14 |
---|---|
[C++ STL] Vector 초기화 시 비용 절감 방법 (0) | 2025.01.01 |
[C++ STL] Pair 클래스 사용하기 (0) | 2024.12.29 |
[C++] fixed와 precision로 소수 특정 자릿수까지 출력하기 (0) | 2024.12.26 |
[C++] getline() 특정 문자가 들어올 때까지 입력 받기 (0) | 2024.12.12 |