파라미터와 리턴값
이전 시간에 함수 파라미터에 정수형 값을 넘겨주는 함수의 예제를 잠깐 봤는데요, 이번 시간에는 함수의 파라미터로 정수 아닌 자료형을 넘기고 리턴하는 함수를 알아볼께요. 지난 시간 예제로 들었던 add_int함수는 정수형 값을 두개 받아서 더한 후에 정수형 값을 반환하는 함수였는데요, 만약 실수형 값을 넘기고 그 합을 리턴하는 함수를 작성하려면 다음과 같이 해야 합니다.
float add_float(float num1, float num2)
{
return (num1 + num2);
}
add_int와 달라진 점은 함수이름이 _int가 아닌 _float로 바뀌었다는 것과 함수 파라미터와 리턴값이 자료형이 int에서 float로 변경된 것입니다.
함수의 파라미터와 리턴값의 자료형(Data type)을 결정할때는 많은 주의를 기울여야 합니다. 다음과 코드를 보도록 하죠.
#include <stdio.h>
int divide_int(int, int);
void main()
{
printf ("10 / 3 = %d\n", divide_int(10, 3));
printf ("10 / 3 = %f\n", (float)divide_int(10, 3));
}
int divide_int(int num1, int num2)
{
return (num1/num2);
}
divide_int 함수는 정수형 값을 두개 넘겨주고 나눈 값을 반환하는 역할을 하는데요, 예상하는 결과는 3.3333....일텐데 결과는 3만 출력이 됩니다. 아!!! 나눈 값이 정수형이 아니라 실수 형이니까 printf에서 %f로 출력을 하면 될지도 모르겠네요. divide_int에서 반환하는 값을 float로 변환하기 위해 두번째 printf에서 (float)divide_int(....)이렇게 형변환 (Type casting)을 했습니다. 여기서 사용한 형변환은 원래는 아닌데 float인 것으로 처리하라는 의미입니다. 결과를 보면....
10 / 3 = 3
10 / 3 = 3.000000
안되네요. 뭐가 문제일까요? 그쵸 자료형에 대한 이해가 조금 부족해서 실수를 했습니다. 정수와 정수의 나눗셈은 항상 정수가 됩니다. 그렇다면 옳은 출력을 위해서는 어떻게 해야 할까요? 앞서 형변환과 리턴값을 변경을 해주면 됩니다.
그래서 나누는 함수를 다음과 같이 바꿔 줍니다.
#include <stdio.h>
float divide_int(int, int);
void main()
{
printf ("10 / 3 = %f\n", divide_int(10, 3));
}
float divide_int(int num1, int num2)
{
return ((float)num1/(float)num2);
}
divide_int 의 리턴을 int에서 float로 변경을 해주고, 두 정수의 나눗셈을 형변환을 통해 실수의 나눗셈으로 바꿔주면 됩니다. 아예 int num1, int num2를 float num1, float num2로 바꿔주면 나눗셈을 할 때 형변환을 할 필요가 없습니다.
함수의 파라미터로 값을 던지기만 할 수 있는게 아니라 값을 받아올 수도 있습니다. 이거는 음... 포인터 개념을 알아야 이해하기가 쉬운데요. 일단 예제를 보시죠.
#include <stdio.h>
void swap (int *pa, int *pb)
{
int t;
t = *pa;
*pa = *pb;
*pb = t;
}
void main ()
{
int x, y;
x = 1; y = 2;
printf ("변경 전 : x=%d y=%d\n", x, y);
swap (&x, &y);
printf ("변경 후 : x=%d y=%d\n", x, y);
}
예제에서 swap() 함수를 보면 파라미터로 int 형 포인터 두개가 있구요. 함수는 두개의 정수의 값을 넘겨받아 교환한 후 다시 파라미터로 받아 확인을 하는 기능을 합니다. 여기서는 포인터를 파라미터로 사용하고 값을 넘겨주고 넘겨받을 수도 있구나 정도만 아시면 되겠습니다.
조금 더 난이도가 있는 예제를 보겠습니다.
....
int compare(void *first, void *second)
{
/* 값을 비교하여 결과를 리턴하는 코드 */
}
void main ()
{
int list1[] = {3, 4, 2, 7, 5, 9, 1}
...
qsort(list1, sizeof(list1)/sizeof(int), sizeof(int), compare);
...
}
main()함수에 있는 qsort()함수는 C언어에서 퀵소트함수를 사용하도록 만들어놓은 라이브러리 함수인데 맨 마지막 파라미터로 compare()함수 포인터를 넘겨 줬습니다. 얘는 함수 포인터라고 하는데 포인터를 공부할 때 다시 다루겠습니다. 이처럼 함수의 파라미터로 다양한 데이터형이 사용될 수 있습니다.
함수를 작성을 할때 함수의 파라미터와 리턴값을 어떻게 할지 많은 고민을 하셔야 오류를 줄이고 더 단단한 코딩실력을 갖출 수 있게 됩니다. 지금 이해가 안된다고 걱정을 할 필요는 없습니다. 프로그램 언어도 우리가 사용하는 자연어와 같이 자연스럽게 사용하려면 시간이 오래 걸리기 때문에 직접 코딩을 하고 다른 사람이 만든 프로그램을 분석해 가면서 익숙해지면 언제 그런 고민을 했는지조차 기억이 안나게 될겁니다.
다음 시간에는 프로그램에서 사용하는 스토리지클래스(Storage class)과 프로그램 구조에 대해 알아볼께요.
'프로그래밍 > C언어' 카테고리의 다른 글
C언어 공부하기 - 배열 (0) | 2020.10.05 |
---|---|
C언어 공부하기 - 스토리지클래스와 프로그램구조 (3) | 2020.08.19 |
C언어 공부하기 - 함수(1) (0) | 2020.08.08 |
C언어 공부하기 - 순환문(2) do~while, break, continue, goto (0) | 2020.07.25 |
C언어 공부하기 - 순환문(1) while, for (0) | 2020.07.23 |
댓글