나의 IT일지
함수 본문
수학에서 함수란 두 집합의 관계를 논리적으로 설명하는 개념으로, f(x) = x+y 같이 왼쪽엔 함수명, 오른쪽엔 수식인 형식을 가지고 있다.
프로그래밍에서도 똑같이 함수라는 개념을 사용하는데, 수학에서 사용하는 개념이 살짝 다르다. 프로그래밍에서의 함수란 나열된 여러 명령들의 묶음으로, 우리가 항상 사용하는 "printf(), scanf()"이 바로 함수의 종류이다.
함수 사용이유
프로그래밍에서 함수를 사용하는 이유는 개발자의 가독성도 있지만, 자주 사용하는 여러 명령들을 묶어놓고 이름을 호출하는 것만으로 편하게 사용하기 위해서 사용한다. 특히 코드가 긴 부분을 중복적으로 사용한다고 할 때 사용이 된다.
예를 들어 두 수의 평균값을 구하는 코드가 있다고 하자.
#include <stdio.h>
void main(){
float a, b, c;
printf("첫번째 값:");
scanf("%f", &a);
printf("두번째 값:");
scanf("%f", &b);
c = (a + b) / 2.0;
printf("평균값: %f", c);
}
1개의 평균값을 구하면 상관이 없지만, 4개의 평균값을 구한다고 하면 코드의 길이가 길어져서 가독성에 문제가 있다. 그래서 코드의 일부를 함수로 만들어서 사용하는 것이다.
#include <stdio.h>
//함수 선언: 어떤 함수를 사용할 것인지 컴파일러에게 알려주는 역할
float call_avg();
float avg(float, float);
//함수 호출 :정의한 함수 사용
void main() {
printf("평균값:%f\n", call_avg());
printf("평균값:%f\n", call_avg());
printf("평균값:%f\n", call_avg());
printf("평균값:%f\n", call_avg());
}
//함수 정의: 함수를 제작하는 것
float call_avg() {
float a, b, c;
printf("첫번째 값:");
scanf("%f", &a);
printf("두번째 값:");
scanf("%f", &b);
c = avg(a, b);
return c;
}
float avg(float x, float y) {
float k;
k = (x + y) / 2.0;
return k;
}
이렇게 위의 코드처럼 함수를 정의해 놓으면, 함수를 호출하는 것 만으로 쉽게 코딩할 수 있게 된다.
함수 정의과 구조
일단, 함수를 정의할 때는 다른 함수 안에서 정의를 할 수 없다. 즉 main함수나 다른 함수와 다른 구역에서 정의를 해야 한다. 그리고 프로그램의 실행과정은 위에서 아래로 진행되기 때문에, 함수의 원형를 선언이 없다면, main함수 보다 전에 함수를 정의해야 한다.
함수는 함수를 제작하고 정의하는 구현부, 함수를 호출하여 사용하는 호출부로 나눠져 있다.
<구현부> 반환형 함수명 (매개변수1,매개변수2....){ 명령1; 명령2; ... return 리턴값 } |
<호출부> 함수명(값1,값2...) |
함수를 만들 때에는 구현부부터 작성을 해야 한다.
- 반환형: 함수가 기능을 수행한 후 돌려줄 값(리턴값)의 형식를 정하는 자료형, void와 정수형, 실수형만 반환형으로 사용할 수 있다.
- 매개변수: 함수의 호출부에서 전달하는 값을 구현부에 받아와 저장하기 위한 변수
- return문: 호출된 메소드가 실행이 끝난 뒤, 함수가 가지는 값으로, 리턴값을 main함수에서의 해당 함수 결과값으로 반환하는 분기문, 이때 return값은 하나만 존재할 수 있다.
구현부의 블록에 명령들이 작성 완료가 되면, main함수에 해당 함수를 호출부형식으로 호출하면 된다.
#include<stdio.h>
int sum(int x, int y) {
printf("두수의 합 : %d\n", x + y);
int result = x + y;
return result;
}
void main(){
printf("%d\n", sum(2,3));
}
위의 코드를 보면, 반환형을 정수형으로 한 sum함수를 정의하고, main함수에는 정의한 sum함수를 호출하는 것을 볼 수 있다.
이때, 매개변수에 인수 "2"와 "3"이 들어가 있는 것을 확인할 수 있다. 이는 sum함수에서 매개변수 x,y에 x = 2, y = 3을 넣고 나온 값은 return문에 의해 값이 변환이 된다. 즉 "sum(2,3) = 5"가 되는 것이다.
결과를 보면, main함수의 실행문이 "printf("%d\n", sum(2,3))"인데, 실행결과가 "5"만 있지 않고 "두수의 합 : 5"가 있는 것을 확인할 수 있다.
이는 sum함수의 "printf("두수의 합 : %d\n", x + y)"때문에 나타나는 현상이다. "printf("%d\n", sum(2,3))"만 있다고 해서 sum함수의 리턴값만 나오는 것이 아니라 sum함수 자체가 실행되는 것을 알 수 있다.
번외) 함수 선언을 하는 이유
#include<stdio.h>
int sum(int x, int y) {
printf("두수의 합 : %d\n", x + y);
int result = x + y;
return result;
}
void main(){
printf("%d\n", sum(2,3));
}
#include<stdio.h>
int sum(int, int)
void main(){
printf("%d\n", sum(2,3));
}
int sum(int x, int y) {
printf("두수의 합 : %d\n", x + y);
int result = x + y;
return result;
}
위의 함수를 이용한 두 예시를 보면, 첫번째 예시는 함수를 선언하지 않는 코드이지만 두번째 예시는 함수를 선언한 코드이다. 이처럼 함수를 선언하지 않아도 main함수부터 실행하기에 실행하는데엔 문제가 없지만, 함수 선언하는 데에는 이유가 있다.
- 컴파일러가 함수 선언에서 반환값의 형태를 미리 확인
- 컴파일러가 함수의 호출 형식에 문제가 없는지 검사
- main함수를 제일 윗쪽에 배치하기 위함