본문 바로가기

C++ 일기

11 - 1. 함수

우리가 수학을 통해 알고있는 함수는 x값이 주어지면, 그 x를 방정식에 대입해 미지수 y를 도출하는 것이다.

프로그래밍에서의 함수도 이와 비슷하다.

함수에 특정 값을 입력하면 그 입력값을 이용하여 결과값을 출력하는 것이다.

 

자판기를 예로 들어보자

식당을 나오는 길에 100원짜리 믹스커피 자판기가 있다.

우리는 이 믹스커피를 마시기 위해 100원을 넣고, 커피 자판기에서 믹스커피를 뽑아 마신다.

여기에서 100원이 함수의 입력값이고, 믹스커피가 결과값이다.

프로그래밍 언어에서는 이 입력값을 매개 변수라고 하고, 결과값을 반환값이라고 부른다.

 

함수는 재사용이 가능하기 때문에 이전에 main함수에서 수행하던 반복작업의 빈도를 줄일 수 있고,

기능을 세분화하여 분리할 수 있게 만들기 때문에 프로그램의 볼륨이 커져도 유지보수 와 수정을 더 쉽게 할 수 있다.

또한 위와 같은 특성 때문에, 코드의 가독성 역시 좋아진다.

 

함수의 선언은 아래와 같다.

#include<iostream>


int Sum(int a, int b);   // 함수의 선언

int main()
{
   
}

int Sum(int a, int b)   // 함수의 정의
{
   int result = a + b;
   return result;       // 반환값
}
// 함수의 내용은 정의 부분의 중괄호 안에 담긴다.

int Sum(int a, int b); 부분은 함수를 선언하는 부분이다.

맨 먼저 자료형을 입력하는데, 이는 함수가  뱉어낼 반환값의 자료형을 선언하는 것이다.

int를 입력하면 그 함수는 int값을 반환해야한다

 

Sum은 함수의 이름이다.

 

소괄호 안의 값 (int a, int b)는 함수에 전달해줄 매개변수이다.

매개변수는 여러개일 수 있으며, 어떤 자료형을 입력할 것인지 자료형도 당연히 같이 선언해줘야 한다.

 

마지막으로 return은 함수가 반환할 값을 적는 곳이다.

앞서 말했던 것 처럼 int형 함수는 int형을 반환해야한다.

반환값은 정의에서 표기한 자료형 외에는 어떠한 값도 올 수 없으며,

void 함수가 아닌 모든 함수는 반드시 반환값을 가져야 한다.

여기서 void함수란, 반환값이 존재하지 않는 함수로, 

함수 호출 후에 함수 내에서 코드를 실행하고 아무런 값도 반환하지 않고 사라지는 함수이다.

 

다음으로는 아래의 int Sum(int a, int b) { } 에 대해 설명하겠다.

다른 부분은 선언에서 설명한 것과 같기 때문에 넘어가겠다.

함수의 정의 부분에서는 함수를 선언했던 것과 같이 입력해주어야 하고, 함수의 내용을 중괄호 안에 채워넣어야 한다.

함수의 내용을 중괄호 안에 넣고, 마지막에 return을 통해 반환값을 알려주기만 하면 끝이다.

입력한 매개변수를 통해 원하는 반환값을 뱉어내기 위한 함수의 내용을 코딩하고,

마지막에 반환할 값을 return 뒤에 적고 세미콜론으로 마무리 지으면 된다.

 

Sum 함수는 이제 정수 a, b 두개를 넣으면 a + b를 뽑아주는 자판기가 된 것이다.

 

이렇게 만들어진 함수는 다음과 같이 사용이 가능하다.

#include<iostream>

int Sum(int a, int b);

int main()
{
   std::cout << Sum(3, 7) << std::endl;
   //출력값 : 10
}

int Sum(int a, int b)
{
   int result = a + b;
   return result;
}

 

 

 

 

 

함수는 기본적으로 매개 변수의 유무와 반환 값의 유무로 4가지의 형태로 분류할 수 있다.

#include<iostream>

//1. 매개 변수와 반환 값이 모두 있는 경우
int Sum(int a, int b){
   int result = a + b;
   return result;
}

//2. 매개변수는 있으나 반환값이 없는 경우 (void함수)
void Print(int num){
   std::cout << num << std::endl;
}

//3. 매개변수가 없고 반환값만 존재하는 경우
int ReadNum(){
   int num;
   std::cin >> num;
   return num;
}

// 4. 매개변수와 반환값이 모두 존재하지 않는 경우
void SayHello(){
   std::cout << "Hello" ;
}

int main()
{
  
}

위와 같은 형태로 다양하게 선언하고 정의할 수 있다. 

함수의 정의는 함수 밖에서 이루어져야 하며, 함수 내부에서도 함수를 호출할 수 있다.

main 함수도 함수인데 다른 함수를 호출하여 사용할 수 있는 것과 동일하다.

 

 

함수를 사용할 때 가장 유의해야하는 것과 메모리의 구조가 연관되어있다.

함수의 변수는 지역변수인데, 지역변수는 함수 호출시에 메모리가 할당되고,

함수가 종료되면 메모리 할당이 해제되어 지역변수에 저장되어있는 데이터가 사라지게 된다.

 

#include<iostream>


int Sum(int a, int b){
   int result = a + b;
   return result;
}
int main()
{
   int result = 0;
   Sum(4, 6);
   std::cout << result;
   // 출력값 0
}

위와 같은 형태의 Sum함수를 main함수를 통해서 호출하면,

출력값으로 4 + 6의 값인 10이 나올 것이라고 생각할 수 있지만 출력되는 값은 0이다.

main함수를 통해 호출된 Sum함수의 result는 함수가 실행되는 동안 result의 값에 10을 저장하지만,

함수가 종료된 후 그 데이터가 사라지기 때문에 main함수의 result값과는 관련이 없다.

함수의 데이터는 오직 반환값을 통해서만 오갈 수 있기 때문에 함수를 통해 값을 얻어오고 싶다면

반드시 반환값이 있는 함수를 호출하여 그 값을 함수의 지역변수로 저장한 후에 사용해야한다.

 

 

함수는 프로그램의 기능을 기능별로 분할할 수 있게 해주며, 그렇게 분할된 기능들을 다시 입력하는 것이 아니라

단순히 함수를 호출함으로써 재사용할 수 있기 때문에 반복적인 작업을 줄여줄 수 있으며,

전체적인 코드의 길이가 짧아지고, 기능별로 묶어 이름을 붙여줄 수 있기에 가독성이 향상된다.

또한 기능별로 분할이 되어있기 때문에, 프로그램에 문제가 생겼을시 어느 곳에서 문제가 일어났는지

파악하기 수월하며, 해당 기능만 수정하여 프로그램을 정상적으로 돌려놓을 수 있기 때문에

프로그램의 볼륨이 커져도 유지보수 하기가 쉽다.

 

 

전체적으로 정리하여 예시로 들어본다면, 나는 이 일련의 과정들이 공장과 비슷하다고 생각했다.

자동차 공장으로 예를 들자면, main함수는 모든것을 조립하는 라인이다.

자동차를 만들기 위해 바퀴 공정에서 바퀴를 가져오고, 문을 만드는 공정에서 문을 가져와 조립한다.

바퀴를 만들기 위해 필요한 재료들은 조립공정에서 원하는 바퀴를 만들 수 있는 재료를 전달해야한다.

바퀴 공정에 바퀴를 만들어달라고 의뢰하면 바퀴를 만들어주고,

문을 만드는 공정에는 속도를 올리라는 지시를 내린다고 가정한다면,

바퀴공정 의뢰는 바퀴를 반환하는 바퀴 함수이고,

문공정 의뢰는 문 공정의 속도를 올리고, 차 문은 가져오지 않는 반환값이 없는 void함수이다.

바퀴 공정에 필요한 재료를 전달하는데, 여기서 재료는 매개변수이다.

문공정에는 아무런 재료도 주지 않고, 문을 받지도 않았기 때문에 반환값도 매개변수도 없는 함수라고 할 수 있다.

'C++ 일기' 카테고리의 다른 글

12. 열거형 타입 enum  (0) 2024.02.26
11 - 2. 함수 오버로딩  (2) 2024.02.26
10. 배열 (array[])  (0) 2024.02.23
9 - 2. 반복문 for  (0) 2024.02.23
9 - 1. 반복문 while  (0) 2024.02.23