1. 함수와 배열
c++에서, 배열 이름을 그 배열의 첫번째 원소의 주소로 인식함
// arr == &arr[0]
#include <iostream>
using namespace std;
const int SIZE = 8;
int sumArr(int arr[], int n);
int sumArr2(int*, int*);
void sizeArr(int* arr);
/*c++에서, 배열 이름을 그 배열의 첫번째 원소의 주소로 인식함*/
// arr == &arr[0]
int main()
{
int arr[SIZE] = {1,2,3,4,5,6,7,8};
int total = sumArr(arr, SIZE);
cout << "This is total1: " << total << endl;
// This is total1: 36
int total2 = sumArr2(arr, arr+SIZE);
cout << "This is total2: " << total2 << endl;
// This is total2: 36
cout << "size of arr[SIZE]: " << sizeof arr << endl;
// size of 'arr[SIZE]': 32 //argument
sizeArr(arr);
// size of 'arr': 8 //parameter
}
/*배열을 전달받을 때에는 배열 전체가 들어오는 것이 아닌, 첫번째 원소의 주소값이 들어옴*/
int sumArr(int arr[], int n) { //int* arr라고 써도 무방
int total = 0;
for (int i=0; i<n; i++)
total += arr[i]; //배열의 원소에 접근하는 대괄호는 배열이든 포인터든 사용가능
return total;
}
int sumArr2(int* begin, int* end) {
int total = 0;
for (int* pt = begin; pt != end; pt++)
total += *pt;
return total;
}
void sizeArr(int* arr) {
//int arr[] 일 때와 int* arr 일 때 결과가 동일함
cout << "size of array as parameter: " << sizeof arr << endl;
// size of array in sumArr(): 8
// 32가 아닌 8이 나옴
}
2. 함수와 구조체
구조체와 함수
- 함수 통해 구조체 자체를 직접 리턴할 수 있고
- 함수의 인풋으로 구조체 형식을 사용할 수도 있음
구조체 규모가 너무 커질 때, 함수는 구조체의 원본이 아닌 복사본으로 작업하기에
- 이때 구조체를 포인터로 사용할 시 훨씬 효율적이게 됨
- 이 경우 원소에 접근하려면 화살표를 사용함
#include <iostream>
using namespace std;
const int MINUTES = 60;
int totalmin(int hour, int minute);
struct Time{
int hour;
int minute;
};
Time sum(Time*, Time*); //구조체와 구조체를 더하여서 구조체를 Return하는 함수
void showTime(Time);
int main()
{
Time market;
market.hour = 2;
market.minute = 20;
Time library = {1, 11};
cout << "Total minutes to market: " << totalmin(market.hour, market.minute) << endl;
cout << "Total minutes to library: " << totalmin(library.hour, library.minute) << endl;
Time total = sum(&market, &library);
showTime(total);
}
/*
Total minutes to market: 140
Total minutes to library: 71
총 3시간 31분 걸렸습니다.
*/
함수 쪼개서 보기 - totalmin
int totalmin(int hour, int minute)
{
return hour * MINUTES + minute;
};
함수 쪼개서 보기 - sum
- 구조체를 return하는 함수
- 입력으로 구조체를 받음
- 이때 구조체의 주소값을 입력으로 받음
**당연하지만, 입력으로 Pointer를 지정해놓으면, 실제 함수 입력으로도 주소값을 넣어야 함(앞에 & 붙여서~)
Time sum(Time* a, Time* b) {
//구조체의 값에서 멤버(원소)로 접근할 때: . (dot)
//구조체의 주소에서 멤버(원소)로 접근할 때: -> (arrow)
Time total;
total.minute = (a->minute + b->minute) % MINUTES;
total.hour = (a->hour + b->hour) + ((a->minute + b->minute) / MINUTES);
return total;
}
void showTime(Time t){
cout << "총 " << t.hour << "시간 " << t.minute << "분 걸렸습니다." << endl;
}
3. 재귀함수
재귀호출: 함수가 자기 자신을 호출할 수 있음
재귀함수: 재귀호출을 하는 함수 - 종결을 위해 보통 If문을 사용
void recurs(argumentList)
//code #1
if (재귀호출조건)
recurs(argumentList)
//code #2
이때 재귀호출이 연쇄적으로 일어나는 동안에는 code#2가 실행되지 않고 유보됨
연쇄가 끊이면, 가장 마지막에 호출된 code#2부터 쭈욱 실행되어 마지막에 최초 code#2를 실행
#include <iostream>
using namespace std;
void countDown(int);
int main()
{
countDown(5);
}
void countDown(int n)
{
cout << "Counting..." << n << endl;
if (n > 0)
countDown(n-1);
cout << n << " 올라간다~" <<endl;
}
/*
Counting...5
Counting...4
Counting...3
Counting...2
Counting...1
Counting...0
0 올라간다~
1 올라간다~
2 올라간다~
3 올라간다~
4 올라간다~
5 올라간다~*/
4. 함수를 지시하는 포인터
함수를 지시하는 포인터
-> 어떠한 함수에 함수의 주소를 매개변수로 넘겨주는 경우, 유용하게 사용할 수 있다.
1. 함수의 주소를 얻는다 (그냥 '함수명'만 입력해주면 됨)
2. 함수를 지시하는 포인터를 선언한다. 이때 함수 포인터 선언 형태가 특이함
1) 반환형 (*포인터명)(매개변수) = 함수명; OR
2)반환형 (*포인터명)(매개변수);
포인터명 = 함수명
3. 함수를 지시하는 포인터를 사용하여 그 함수를 호출한다.
#include <iostream>
using namespace std;
int func(int);
//함수 포인터에서 괄호를 빠뜨리지 말 것 !
int main() {
int (*ptr_func)(int) = func;
cout << ptr_func(10) << endl; //1000
cout << (*ptr_func)(10) << endl; //1000
int (*ptr_func2)(int);
ptr_func2 = func;
cout << ptr_func2 << endl; //1
cout << (*ptr_func2)(10) << endl; //1000
}
int func(int a) {
return a*100;
}
//함수의 주소는 함수 당 하나밖에 없음! 입력이 어떻든, 함수마다 고유한 값~
'개발 > c++' 카테고리의 다른 글
[c++] Call by value vs Call by reference (0) | 2023.09.03 |
---|---|
[c++] 메모리의 세 가지 영역 : 데이터, 스택, 힙 (0) | 2023.09.03 |
[c++ 프로그래밍 입문] 5-1. 함수의 기초 (0) | 2023.08.30 |
[c++ 프로그래밍 입문] 4. Branch Syntax (분기 구문, 조건문) (1) | 2023.08.23 |
[c++ 프로그래밍 입문] 3. 반복문 (0) | 2023.08.22 |