안녕하세요! 코딩하는 경제학도 쏘코입니다.
오늘 포스팅의 주제는 C++의 핵심, 함수입니다.
비단 C++ 뿐만이 아니라 거의 모든 프로그래밍 언어에서 가장 중심이 되는 요소가 함수가 아닐까 생각합니다.
그렇다면 바로 들어가시죠!
목차
0. 이미 존재하는 함수
여러분은 아마 중학교 1학년때 함수에 대한 기초를 떼고 오셨을 것이라고 생각합니다.
간단하게 설명드리면, 무엇이든 *2를 해주는 박스에 4라는 숫자를 넣었을 때 8이 출력됩니다.
여기서 *2를 해주는 박스가 함수가 되고, 4가 매개변수, 8이 리턴값이 됩니다. 그리고 4*2를 하는 과정이 명령문이 됩니다.
이것을 수식으로 표현하면 f(x) = x * 2이고, f(4) = 8이 되겠죠?
C++에서의 함수도 똑같습니다.
이미 만들어진 함수를 사용할 때는 f 대신 함수의 이름을 쓰고, ( ) 안에는 매개변수를 넣어줍니다.
조금 다른 점이 있다면 C++에서의 함수는 수학에서의 함수와는 다르게 간혹 필요에 따라 여러 개의 변수를 넣어줄 수 있습니다.
이렇게 함수를 만들면 반복되는 작업을 매번 구현할 필요 없이 함수를 이용해서 간단하게 처리할 수 있습니다!!
cmath라는 라이브러리에 존재하는 sqrt라는 함수를 사용해보겠습니다.
이 함수는 루트값을 반환해주는 함수입니다.
루트 4는 2죠?
C++에서는 이것을 sqrt(4)로 표현합니다.
이걸 바로 쓸 수는 없고, sqrt가 들어있는 라이브러리를 include해야합니다.
첫 포스팅에서 iostream이라는 라이브러리를 항상 불러온다고 이야기했습니다.
이것처럼 전처리 과정에서 sqrt가 들어있는 <cmath> 이라는 라이브러리를 불러옵니다.
그러고 나면 sqrt를 사용할 수 있습니다. 생각보다 별 거 없죠?
(TMI : sqrt라는 함수는 double값을 반환하기 때문에 일반적으로 double형 변수에다가 넣어주어야 합니다)
추가로 cmath라는 라이브러리 안에는 정말로 다양한 수학과 관련된 함수들이 존재합니다.
이것들을 필요에 따라서 매개변수 규칙을 반드시 지켜서 쓰시면 됩니다!!!
(매개변수의 개수를 잘못 사용하면 대부분 초기값이 없기 때문에 돌아가지 않습니다)
이외에도 <algorithm>(최대값, 최소값, 정렬 등), <ctime>(작동 시간), <cctype>(글자변환), <cstdlib>(랜덤값) 등등 다양한 기본 라이브러리가 존재합니다.
이것들을 #include <~>를 통해 불러와서 사용하실 수 있습니다.
1. 사용자 정의 함수
이미 만들어져 있는 함수가 아닌, 직접 함수를 만들어서 사용할 수도 있습니다.
대신 함수를 선언할 때의 규칙이 있습니다.
- 함수의 앞에 리턴형이 붙습니다.
- f 대신 함수의 이름이 붙습니다.
- ( ) 안에는 똑같이 매개변수가 붙는데, 특징이라면 여러 개의 매개변수가 들어갈 수 있습니다.
- 매개변수의 타입을 매개변수 앞에 써줘야 합니다.
- { } 안에는 함수가 어떻게 동작하는 지에 대한 명령문이 들어갑니다.
아래 사진에 함수의 선언에 대한 자세한 설명이 되어있습니다.
아래는 위 사진의 square_root 함수를 실제로 구현한 코드입니다.
double형의 결과값을 출력하는 square_root라는 이름을 가진 함수이고, 매개변수로 double형 변수 1개를 받습니다.
(x라는 매개변수 이름은 { } 명령문 안에서 매개변수를 사용하기 위한 이름이기 때문에 다른 것으로 바뀌어도 상관이 없습니다. 다만 바꾼다면 명령문 안에서도 x 대신 바꾼 변수로 바꿔야 합니다!)
그 값은 { } 안에서 사용되고, 함수의 결과로 계산된 root라는 값이 결과값으로 나오게 됩니다.
(do while문을 통해 square_root의 정확성을 계속해서 높여주는 모습입니다!)
이 함수를 이용해 얻은 값을 main함수 내에서 출력해보면 이미 cmath에 존재하는 sqrt함수와 비교해보았을 때 오차가 0.0001 미만인 것을 알 수 있습니다.
아래는 좀 더 쉬운 예시입니다.
값을 2개를 받아서 출력을 하는 프로그램인데, 출력하는 명령을 담은 함수 prompt()에 저장해서 사용했습니다.
prompt 함수는 void가 리턴값이기 때문에 별도의 return은 들어가지 않습니다.
(void가 아닌 경우 리턴값으로 설정한 요소가 return을 통해 반환되지 않으면 컴파일 에러가 발생합니다!)
위 프로그램이 작동하는 순서입니다.
영어를 간단하게 번역해보면
프로그램이 시작하면서 main()함수가 돌아가고 prompt()함수가 작동합니다.
main함수 내에서 prompt함수를 만나면 main함수 위에 존재하는 함수들 중 prompt라는 이름을 가진 함수를 찾게 되고 그 함수의 명령문을 실행합니다.
(컴파일러는 위에서부터 순서대로 읽어내려오다가 main이 끝나면 더 이상 읽지 않습니다. main함수 아래에 어떤 함수가 있다면 그 함수를 읽지 못했기 때문에 함수를 사용할 수 없겠죠?)
그리고 다시 main함수로 돌아와서 나머지 작업을 하게 되는 것이죠.
위 코드에서는 prompt()가 총 2번 존재하기 때문에 2번 올라가게 되겠네요!
매개변수에 대해 조금 더 자세히 알아보겠습니다.
일반적인 함수에서는 자료형과 변수이름(예를 들면 int x)이 들어가는데, 이것을 Pass by Value라고 말합니다.
value값을 그대로 전달하는 것인데, 여기서의 변수는 함수 안에서만 쓰이고 함수가 끝나면 메모리에서 사라집니다.
main함수 내에서 x라는 변수를 만들었다고 하더라도 다른 함수 내에서는 x에 접근할 수 없습니다.
(나중에 배우겠지만, &를 통해서 가능합니다.)
아래 예시에서 main함수의 x와 increment함수의 x가 다른 것을 확인할 수 있습니다.
main함수 내에서의 x는 함수가 작동한 후에도 그대로 5인데, increment 함수 내의 x는 5에서 6으로 증가했죠?
이것처럼 Pass by Value의 경우 함수 내에서의 변화는 함수 밖에 영향을 끼치지 않습니다.
이렇게 직접 함수를 만들어 사용할 때 함수의 선언만 main함수 위에 적고, 구현부는 main함수 아래에 적는 경우가 있습니다.
이런 케이스는 어떤 함수를 만들었는지 간략하게 파악하는 데에 도움이 되기도 하고, 나중에 배울 cpp와 헤더의 분리에서도 사용됩니다.
함수의 선언의 경우 리턴형, 함수의 이름, 매개변수만 적고 세미콜론(;)을 붙입니다. (매개변수의 변수값은 생략해도 됩니다!)
그리고 실질적인 구현부는 main함수 아래에 다시 적는 것이죠.
이렇게 작성하면 함수가 main함수 아래에 구현되어도 위에서 선언문을 읽었기 때문에 파일 내부의 함수를 찾아서 그 함수를 사용할 수 있게 됩니다.
2. 부록 : main함수
main함수가 반드시 필요한 것이라는 것은 알았지만 함수에 대해서 정확하게 알지 못했기 때문에 이해에 어려움이 있었을 수 있을 것 같습니다..
그래서 이렇게 따로 main함수에 대해서 적어보려고 합니다.
main함수는 함수 중에서도 조금 독특한 친구입니다.
main함수는 C/C++ 프로그램의 시작점으로, 모든 프로그램은 단 하나의 시작점만 가지고 있어야 합니다.
여러 개 가지고 있으면 컴파일 에러가 발생하게 됩니다.
그리고 이 main함수를 통해 우리는 프로그램을 실행할 수 있죠.
위 조건 외에는 일반적인 사용자 생성 함수와 동일합니다.
int main() { }의 형식이기 때문에, 리턴값으로 int형을 받아야 정상입니다.
하지만 위에서는 main함수에서 리턴값을 안 받은 경우가 많죠?
옛날에는 개발자가 반드시 return 0;을 명시적으로 써 주어야 했지만,
C99(1999년 버전 C) 이후로는 return 0을 생략하더라도 컴파일러에서 알아서 0을 넣어줍니다.
그래도 명시적으로 써 주는 것이 올바른 사용법이니 되도록이면 작성해주세요!
(TMI : 저도 항상 작성하는 편입니다만 수업 자료에서는 생략되어 있습니다..)
이번 포스팅에서는 함수의 기본에 대해 알아보았습니다.
이전 포스팅에서 두루뭉술하게 넘어갔던 main함수에 대한 궁금증이 조금이나마 풀리셨으면 좋겠습니다!
그렇다면 다음 포스팅에서는 함수의 확장판! 으로 돌아오도록 하겠습니다!
오늘도 읽어주셔서 감사합니다 :)
최근댓글