[C++ Primer Plus] Chapter 7. 함수
Table of Contents
C++ 기초 플러스 책을 읽고 공부한 노트입니다.
함수 #
double Solution(int); // 원형
Solution(num); // 호출
double Solution(int num) // 정의
{
return num * 3.0f
}
함수의 원형이 필요한 이유 #
- 함수의 원형은 컴파일러에게 함수의 인터페이스를 알려준다. 즉, 리턴값과 매개변수의 데이터형을 알려준다.
- 함수는 자신의 리턴값을 CPU의 지정된 레지스터/메모리에 복사한다. 어떤 형의 값인지는 자신의 정의를 본다.
- 호출한 함수가 그 위치에서 값을 꺼내온다. 함수 원형을 보면 리턴값이 뭔지 알 수 있으므로 컴파일러는 그 위치에서 몇 바이트를 꺼내야 하는 지 알고 있다.
함수 원형의 매개변수 #
double Solution(int); // 매개변수 이름을 생략해도 된다.
double Solution(...); // 매개변수 리스트가 무엇인지 확인하지 않겠다는 뜻이다.
double Solution(int x);
Solution(5);
// 5 = 실제 매개변수 = 함수에 전달되는 값 = argument
// x = 형식 매개변수 = 전달되는 값을 넘겨받는데 쓰는 변수 = parameter
// 매개변수란 argument가 parameter에 대입되는 것이다.
배열 매개변수 #
int nums [3] = {1, 2, 3};
Solution(nums, 3);
void Solution(int arr [] , int size);
void Solution(int * arr , int size); // 같은 의미이다.
// 이렇게 할 수도 있다.
Solution(nums, nums + 3);
void Solution(int * begin, int * end)
cout << sizeof(nums) << endl; // 12. 배열 전체의 크기.
cout << sizeof(arr) << endl; // 4. 포인터 변수의 크기.
// 따라서 매개변수로 배열의 크기를 넘겨주려면 따로 추가적인 매개변수가 필요하다.
// 배열의 값을 변경하는 걸 원하지 않으면 const로 선언해준다.
void Solution(const int arr []);
포인터와 const #
표기 | ptr = &other; |
*ptr = 3; |
의미 |
---|---|---|---|
const int * ptr |
O | X | ptr 을 이용해서 num 의 값 변경 불가. |
int * const ptr |
X | O | ptr 이 가리키는 값을 변경 불가. |
int num1 = 5;
const int * ptr = &num1; // 만약 num이 const라면 ptr은 무조건 const여야 한다.
int num2 = 3;
ptr = &num2 // (O) ptr에 새로운 val이라는 값을 가리키게 할 수는 있다.
*ptr = 3; // (X) 하지만 ptr을 이용해서 그 값 자체를 바꿀 수는 없다.
int num1 = 5;
int * const ptr = &num1;
*ptr = 3; // (O) num의 값을 변경할 수는 있다.
int num2 = 3;
ptr = &num2; // (X) 하지만 ptr을 이용해서 다른 값을 가리키게 할 수는 없다.
2차원 배열 매개변수의 전달 #
- 배열 포인터
// 포인터다. 4개의 int형 원소들을 가지고 있는 배열을 지시하는 포인터다.
int (*arr) [4];
int arr[][4];
- 포인터 배열
// 배열이다. 4개의 int형 포인터들을 가지고 있는 배열이다.
int *arr [4];
arr[3][4]
==*(*(arr + 3) + 4)
arr[3]
==*(arr + 3)
- 4개의 원소를 가지고 있는 3번째 행 배열의 이름이다. (
sizeof(arr[3])
하면 16바이트)
- 4개의 원소를 가지고 있는 3번째 행 배열의 이름이다. (
C스타일 문자열의 전달 #
void Solution(const char * str); // 문자열은 마지막이 널문자이므로 배열 크기를 넘길 필요가 없다.
char name[4] = "Kim";
Solution(name);
char * nik = "KeKe";
Solution(nik);
구조체, string의 전달 #
- 일반 변수처럼 값으로 전달된다.
array 객체의 전달 #
std::array<double, 4> expenses;
Solution(expenses);
void Solution(std::array<double, 4> * exp)
{
cout << (*exp)[0] << endl;
}
// exp는 포인터다.
// *exp는 객체이다.
// (*exp)[0] 은 그 객체에 있는 원소이다.
함수 포인터의 전달 #
double Function(int num);
// pf는 함수를 지시하는 포인터, *pf는 함수 자체.
// 함수 포인터
void Solution(double (*pf) (int))
{
double result = pf(5); // (*pf)(5)
}
// 함수 포인터들의 배열
void Solution(double (*pf [3]) (int))
{
double result = pf[0](5); // (*pf[0])(5)
}
// 함수 포인터의 포인터
void Solution(double (**pf) (int))
{
double result = pf[0](5); // (*pf[0])(5)
}
// 함수 포인터들의 배열의 포인터
void Solution(double (*(*pf) [3]) (int))
{
double result = (*pf)[0](5); // (*(*pf)[0])(5)
}
// pf를 함수 포인터형으로 쓸 수 있다.
typedef double (*pf) (int);
pf function = f1;