티스토리 뷰

Programming/C++

C++ 독학 로그 06 - 1. 함수

quokka_dev 2018. 8. 18. 03:42


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
using namespace std;
 
int main()
{
    int i, j;
 
    for (i = 1; i < 10; i++) {
        for (j = 2; j < 5; j++) {
            cout << j << " * " << i << " = " << i * j << "   ";
            if (j == 4) {
                cout << "\n";
                continue;
                if (i = 9) {
                    cout << "\n\n";
                    continue;
                }
 
            }
        }
    }
    for (i = 1; i < 10; i++) {
        for (j = 5; j < 8; j++) {
            cout << j << " * " << i << " = " << i * j << "   ";
            if (j == 7) {
                cout << "\n";
                continue;
                if (i = 9) {
                    cout << "\n\n";
                    continue;
                }
            }
        }
    }
}
cs



일단 저번시간 예제의 답입니다. 참고하시고 자신이 작성한 코드와 비교해보시길 바랍니다.


이번주, 이거저거 밀렸던 일과 여름휴가로 블로그를 오랜만에 작성하게 되었습니다. 그리고 기쁜 소식 하나는 제 블로그를 보고 공부하시는 분들이 있다고 알려주신 댓글입니다.


처음에 이 블로그를 개설하고 이 블로그에 들어와서 얼마나 많은 사람이 내 정리글을 읽게 될까 잠시 생각해본적은 있었습니다만 설마 있겠나 싶어서 저혼자 편하게 쓰자고 작성하게 되었는데요


댓글이 달리고나서부터는 블로그나 sns가 나만의 개인공간이 아님을 깨닫고 이번 강의부터는 존댓말로 작성합니다.



오늘은 함수에 대해서 기록합니다. 


함수는 우리가 프로그램을 만들때 프로그램에서 가장 많은 부분을 차지하는것이 바로 함수입니다.


우리가 항상 코드작성할때 제일 먼저 하는것이 라이브러리를 참조시키고 사용할 네임스페이스를 선언해준다음 메인함수를 불러옵니다.


이 메인함수도 함수입니다. 함수는 그 자체로 하나의 프로그램인 것입니다. 우리가 쓰는 프로그램의 기능이고 도구를 만들어주는것이 이번 강의의 핵심입니다.


그럼 함수를 작성하는 방법에 대해서 알아보겠습니다.



함수


함수는 재사용이 가능한 코드를 정의하고 코드를 조직화하며 간략화시켜줍니다. 


우리는 앞시간에서 선택문과 반복문까지 배우면서 프로그램의 기본 요소들을 알아보았습니다. 그 기본요소들은 한번 코드를 실행시키면 한번밖에 쓰지 못하며, 선택문이나 반복문을 탈출하고나서 다시 그 반복문을 쓰기 위해서는 똑같은 반복문을 또 작성해줘야합니다.


이런 부분을 간략화하고 재사용이 가능하게 만드는것이 함수입니다. 예제를 통해 이해해봅시다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
int sum = 0;
for (int i = 1; i <= 10; i++
    sum += i; 
cout << "Sum from 1 to 10 is " << sum << endl;
 
sum = 0;
for (int i = 20; i <= 37; i++)
    sum += i; 
cout << "Sum from 20 to 37 is " << sum << endl;
 
sum = 0
for (int i = 35; i <= 49; i++)
    sum += i; 
cout << "Sum from 35 to 49 is " << sum << endl;
cs


다음 예제는 1부터 10, 20부터 37, 35부터 49까지의 수를 더하는 예제입니다. 


지금까지 우리가 배운 내용으로만 작성하면 이렇게 작성할 수 있습니다만 코드를 자세히 보면 같은 형식의 코드를 숫자만 바꾸어서 세번 작성했다는 것을 알 수 있습니다.


이 방식은 굉장히 비효율적이며 무식한 방법입니다. 이 방식을 탈피하기 위해 있는것이 함수입니다.


이 형식의 코드를 함수로 만들어서 정의해주고 함수를 사용하게 되면 같은 코드도 굉장히 효율적으로 사용가능합니다. 아래는 함수를 사용하여 간략화한 코드입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int sum(int i1, int i2)
{
    int sum = 0;
    for (int i = i1; i <= i2; i++)
        sum += i;
 
    return sum;
}
 
int main()
{
    cout << "Sum from 1 to 10 is " << sum(110<< endl;
    cout << "Sum from 20 to 37 is " << sum(2037<< endl;
    cout << "Sum from 35 to 49 is " << sum(3549<< endl;
 
    return 0;
}
cs


이런식의 코드방식은 훨씬 효율적이며 재사용이 가능합니다.


잠시 이 예제를 보며 함수를 어떻게 작성하는지 알아봅시다.


1행에서 함수의 선언이 나옵니다. 함수가 다룰 데이터유형을 정해주고, 함수의 모양을 결정하는 것이죠.


앞으로 1행에서처럼 sum(i1, i2) 형태로 코드를 적으면 이 함수를 호출하여 사용하게 된다고 알려주는 것이죠.


2행부터 8행까지 이 함수가 무슨 기능을 하는지 정의해주고 있습니다.


3행에서 5행까지 내용은 정수 i1부터 i2까지 반복문을 사용하여 더해주고 있습니다. 


그리고 7행에서 sum의 값을 반환해줍니다.


그리고 다시 10행부터 메인함수가 시작합니다.


첫번째 강의에서도 설명하였듯 메인함수는 프로그램이 시작되면 무조건 제일 먼저 실행하는 함수라고 하였습니다.


메인함수에서 출력을 세번 하게되는데 출력의 내용은 함수를 불러 함수의 인수값을 모두 더한 값을 출력하고 한줄 내립니다.


이걸 세번 출력합니다. 원한다면 같은 방식으로 더 많이 출력할수도 있습니다.


메인함수에 반복문을 넣어서 많은 수의 출력을 할수도 있습니다. 


함수의 기능은 이런것입니다. 정말 편리하죠?



함수의 사용법


이제 함수를 사용하는 방법을 알아봅시다.


함수는 함수의 이름, 매개변수, 반환값 유형, 함수 몸체로 이루어져 있습니다.


이 함수를 먼들어 주는 것을 "함수를 정의한다"고 합니다.


함수를 정의할 때는


1
2
3
4
returnValueType 함수이름(매개변수 목록)
{
    //함수 몸체;
}
cs


로 정의합니다.


이렇게 생기면 전부 함수입니다.


1행을 함수 헤더라고 하고 2~4행부분의 블록안을 함수 몸체라고합니다. 


함수 헤더에서 returnValueType의 의미는 함수가 반환할 반환 값의 데이터 유형을 말합니다. int인지 double인지 bool인지 아니면 반환값이 없는지.


반환값이 있는 함수는 "값 반환 함수" 라고 합니다. 만약 반환값이 없는 함수를 정의한다면 반환값 데이터 유형에 "void"라고 적으시면 됩니다.


그래서 반환값이 없는 함수는 "void함수" 라고합니다. 


함수 헤더에서 선언된 변수는 "매개변수"라고 합니다. 함수가 호출되면 매개변수를 통해 값을 전달하게 됩니다.


그리고 함수를 호출하는 쪽의 매개변수를 "실 매개변수" 또는 "인수"라고 합니다.


매개변수는 선택사항이라서 사용해도 되고 안해도 됩니다. 매개변수가 없는 함수들도 존재합니다.


이 함수이름과 매개변수 목록들은 전부 함수 서명의 구성요소가 됩니다. 말이 어려우니 다음에 자세히 알아봅시다.


마지막으로 함수 몸체입니다.


함수 몸체에서는 함수가 수행할 내용을 정의하는 내용으로 채워집니다. 이부분은 프로그래머가 사용하고자 하는 내용으로 채우는 부분이라 이렇게 저렇게 우리가 지금껏 배워왔던 내용들로 작성하여 원하는 기능을 동작하게끔 문법에 맞춰 작성해주시면 됩니다.


마지막으로 함수가 반환할 값을 "return"문을 사용하여 값을 반환해줘야 합니다. void함수는 반환값이 없으니 return문을 적지 않지만, 값 반환 함수는 반드시 return문이 필요합니다. 


함수가 그 값을 혼자만알고 끝나버리면 함수를 사용한 의미가 없잖아요?



함수 호출


함수를 호출할때는 한가지만 알면됩니다.


"메인함수보다 사용하고자 하는 함수가 먼저 선언되어야 한다."


그렇지 않으면 메인함수에서 컴퓨터는 함수를 적어놔도 함수가 존재하지 않는다고 인식합니다.


컴퓨터는 있는것 주어진것만 가지고 계산을 하는 기계이기 때문에 명령을 내리기 전에 먼저 재료들을 보여주고 있다고 알려줘야 갖다 쓰기 때문입니다.


그래서 함수를 먼저 선언, 정의 해주고 메인함수를 적고 프로그램을 작성합니다.


제가 읽고 독학하는 이 책에서는 설명할때 활성레코드, 호출스택, 실행스택, 실행시간스택, 기계스택, 등등을 설명해주고 있습니다만. 읽어봐도 잘 이해되지않고 초보 프로그래머들에게는 매우 어려운 이야기 이므로 설명생략하겠습니다.


이 내용을 간단히 짚고 넘어가자면, 내가 정의한 함수와 메인함수간의 동작 과정을 설명합니다.


메인함수에서 사용할 값을 내가 정의한 함수로 받아와서 함수를 실행하고, 함수가 반환한 값을 다시 메인함수로 받아와서 사용하게 된다는 내용입니다.


한줄로 후려쳤기때문에 내용이 정확하지 않을 수 있음을 기록해두겠습니다.



void함수


void함수는 반환값이 없는 함수라고 앞서 설명드렸습니다. 이 함수가 뭔지 구체적으로 살펴보겠습니다.


void함수는 반환값이 없기때문에 호출할때는 한 문장(한줄의 문장, 세미콜론으로 끝나야함)으로 호출해야하며 수식이나 대입식에 void함수를 포함시킬수 없습니다.


1
2
3
printgrade(score); // 이건 되고
 
cout << printgrade(score) << endl; //이건 안됨
cs


그리고 void함수는 return문이 필요없지만 예외적으로 정상적인 제어흐름을 빠져나가기 위해 return문을 사용하여 비정상적인 상황에서 프로그램을 종료하도록 유도할수 있습니다.


이것을 예외처리라고 하는데 일단 void함수의 예외처리는 "return ;"이렇게 사용합니다. 알아두면 좋은 꿀팁!



함수 오버로딩


함수 오버로딩은 함수 서명은 다르지만 같은 이름의 함수를 정의할 수 있게 해주는 기능입니다.


사실 이 기능은 객체지향인 C++에는 있는 기능이고 절차지향인 C언어에는 없는 기능입니다. 함수 오버로딩을 쉽게 말하면,


같은 이름의 함수로 다른 데이터유형의 매개변수들을 사용하기 위해 생겨난 것입니다.


예제로 보여드리겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
using namespace std;
 
// 두 정수 중 큰 수 반환
int max(int num1, int num2)
{
    if (num1 > num2)
        return num1;
    else
        return num2;
}
 
// 두 double형 값 중 큰 값 반환
double max(double num1, double num2)
{
    if (num1 > num2)
        return num1;
    else
        return num2;
}
 
// 세개의 double형 값 중 최댓값 반환
double max(double num1, double num2, double num3)
{
    return max(max(num1, num2), num3);
}
 
int main()
{
    // int 매개변수가 있는 max함수 호출
    cout << "the maximum between 3 and 4 is " << max(34<< endl;
 
    // double 매개변수가 있는 max 함수호출
    cout << "the maximum between 3.0 and 5.4 is " << max(3.05.4<< endl;
 
    // 3개의 double변수가 있는 max 함수호출
    cout << "the maximum between 3.0, 5.4, and 10.14 is " << max(3.05.410.14<< endl;
}
cs


함수가 총 세개가 정의되었는데 세 함수 모두 이름이 같습니다. 원래 일반적인 경우, 같은 이름의 함수가 존재하면 구문오류가 납니다.


그러나 C++의 기능중 오버로딩을 이용하면 같은 이름의 함수를 다루고자하는 매개변수를 달리해주면 전부 다른 함수로 인식하고 구문오류없이 사용이 가능합니다. 어떻게 가능한지 알아보겠습니다.


먼저 5~11행까지의 max(n1, n2) 함수는 int 형을 다루고 있으며, 두 정수중 더 큰 수를 반환하는 함수입니다.


같은 이름으로 14~20행 까지의 max함수는 정수가 아니라 실수의 매개변수를 다룹니다. 여기서 함수의 오버로딩이 발생했고, 오류없이 동작하는 함수를 만들었습니다.


바로 아래 22~26행까지 max함수는 매개변수의 개수가 2개가 아니라 3개를 다룸으로써 이름은 같지만 전혀 다른 새로운 함수를 정의합니다.


그래서 아래 main()함수에서 함수들을 호출할때 엉키지 않고 정확하게 호출이 되는것을 알수 있습니다.


여기서 중요한 점은 세개의 오버로딩된 함수들이 있으므로 매개변수를 어떻게 넣어주느냐에 따라 호출되는 함수들이 다르다는 점입니다.


정수형태로 max함수를 부르면 5~11행의 max함수가 호출되고, 두 인수중 어느 하나라도 실수형으로 함수가 호출된다면 5~11행의 max함수가 아니라 14~20행의 max함수를 호출합니다.


같은 원리로 2개의 실수 매개함수를 호출하는 것이아니라 3개의 실수 매개함수를 호출하게되면 23~26행의 함수가 호출된다는 것이죠. 그래서 같은이름의 함수를 호출하여도 오류 없이 정확하게 동작할 수 있는 것입니다.



함수 원형


함수 원형은 굉장히 좋은 기능입니다.


우리는 앞서 함수를 정의할때 메인함수보다 먼저 함수를 정의해주어야 한다고 배웠습니다만, 그렇게 되면 너무 앞에서 무거워져서 프로그램을 돌리는 속도가 줄어들지도 모릅니다.


그래서 우리는 한가지 방법을 통해 이런 가독성 떨어지는 코딩방식을 벗어날수 있습니다. 바로 함수원형을 선언하는것입니다.


앞서서 함수의 생김새를 설명할때 함수헤더와 함수 몸체에 대해 설명드렸습니다.


함수 원형은 함수 헤더 부분을 메인함수 이전에 선언해주고, 메인함수가 끝난 다음 함수의 몸체까지 정의해주는 것이 함수 원형의 사용법입니다.


단순합니다. 이것만 지키면 조금더 코드를 짤때 효율적이고 가독성을 높일수 있게됩니다.




오늘은 여기까지 알아보고 다음시간에 함수의 조금더 깊은 부분을 공부해봅시다.




최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/06   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
글 보관함