본문 바로가기
프로그래밍/C

여러 가지 함수 유형

by 길냥이 2025. 4. 23.
728x90


목차

  1. 매개변수가 없는 함수
  2. 반환값이 없는 함수
  3. 매개변수와 반환값 모두 없는 함수
  4. 재귀 호출 함수

 

1. 매개변수가 없는 함수

함수의 원형은 

반환형 함수명(매개변수)의 형입니다.

하지만 int main()처럼 매개변수가 없는 함수도 존재하죠.

 

뭐, 이전에 설명할 때 int main()과 int main(void)를 바꿔서 쓸 수 있지만, 문법적으로 C에서 ()은 인자 미정이라는 상태에요.

즉, 받을 수도 안 받을 수도 있다는 거죠. 그리고 구식이고요.

 

반대로 int main(void)는 인자를 안 받음, 즉 매개변수가 없음을 의미해요. 코딩을 엄격하게 하기 위해서는 이게 좋아요.

함수를 선언할 때도 앞으로는 int sum(void)식으로 선언할 거니까 알아주세요.

 

이전에 함수를 만들 때에는 매개변수를 받았지만, 그냥 함수 안에서 scanf랑 합을 처리하면 매개변수는 필요없지 않을까요?

바로 실습해보죠.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int sum(void);

int main(void)
{
	int result = 0;

	result = sum();

	printf("합산된 값은 %d입니다.\n", result);

	return 0;
}

int sum(void)
{
	int a = 0;
	int b = 0;

	printf("숫자 2개를 입력하세요:");
	scanf("%d %d", &a, &b);

	return (a + b);
}

좋아요, 실행하면..

 

숫자 2개를 입력하세요:20 30
합산된 값은 50입니다.

잘 굴러갑니다.

 

흠, 근데 함수를 호출할 때는 void를 쓰지 않네요?

위에도 말했지만, void는 매개변수를 받지 않는 것을 의미해요. 

즉, void를 인수로 보내면 안된다는 겁니다.

 

하지만 괄호는 없으면 안돼요. 괄호가 없으면 그냥 변수로 취급되어버립니다.

 

2. 반환값이 없는 함수

함수는 기능에 따라 형태가 결정됩니다.

사실 화면에 출력하는 것도 함수에 넣어 버리면 반환값을 줄 필요도 없어요.

 

그럴 때는 매개변수의 빈자리에 void를 사용했던 것처럼 반환형의 자리에 void가 사용됩니다.

그럼 바로 실습해보죠.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

void sum(int x);

int main(void)
{
	int x = 1000;
	sum(x);

	return 0;
}

void sum(int x)
{
	int a = 0;

	printf("숫자를 입력하세요: ");
	scanf("%d", &a);

	printf("합산된 값은 %d입니다.\n", a + x);
}

매개변수는 있지만 반환형이 없습니다. 그래서 반환값을 main함수 내에서 받지도 않죠.

 

심지어 아래쪽 함수에서는 return도 생략된 걸 볼 수 있습니다. 

어짜피 함수에서 반환값을 줄 필요도 없는데 말이죠...

물론 중간에 return문을 넣어서 사용할 수는 있습니다.

 

3. 매개변수와 반환값 모두 없는 함수

귀찮아요! 그냥 다 버려버립시다.

main문은 함수나 돌리도록 하세요!

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

void sum(void);

int main(void)
{
	sum();
    
	return 0;
}

void sum(void)
{
	int a = 0;
	int b = 0;

	printf("숫자를 입력하세요: ");
	scanf("%d %d", &a, &b);

	printf("합산된 값은 %d입니다.\n", a + b);
}

물론 이래도 됩니다.

결과는 다음과 같아요.

 

숫자를 입력하세요: 30 80
합산된 값은 110입니다.

 

근데 이럴거면 그냥 main문 안에 넣어버리는거랑 뭐가 다르지...

 

4. 재귀 호출 함수

재귀 호출 함수(recursive call function)은 자기 자신을 호출합니다.

다른 함수들이랑 다르게 말이죠, 다른 함수는 보통 다른 함수를 호출해요.

 

만들기는 간단합니다. 함수 안에 자기 자신을 호출하는 문장을 넣으면 됩니다.

 

한번 만들어볼까요.

#include <stdio.h>

void apple(void);

int main(void)
{
	apple();

	return 0;
}

void apple(void)
{
	printf("apple");
	apple();
}

당신은 죄악이 등을 타고 오르는 것을 느꼈다. 이 코드를 실행하면 멈추지 않을 것이다. CPU가 끔찍한 시간을 보낼 거야,,

 

chatgpt 왈

물론, CPU가 불타지는 않습니다. 

 

한번 돌려보시면 결과는 다음과 같아요.

apple ×(637)

엄...

왜 이럴까요? while이나 for문은 무한으로 돌려도 안 터지던데 말이에요...

 

사실 그 이유는 메모리 구조의 차이인데, 함수는 돌릴 때마다 그걸 하나씩 더 써 내려가요.

즉 for문이나 while문의 경우

for<->{ } 순으로 처리한다면

 

저런 재귀 호출 함수는

apple

 ㄴapple

     ㄴapple

         ㄴ...

식으로 처리하기 때문에 계속 메모리 공간을 소모해요. 그러다 할당된 공간을 가득 채우면.. 펑펑펑

 

그럼에도 재귀함수는 문제 코드와 구조가 비슷하고, 반복문과 다르게 코드를 간단하게 바꿔먹을 수 있어요. 자료구조 관리에도 수월하고요.

하지만 종료 조건이 없으면 터지고, 메모리 공간을 계속 퍼먹다 보니 성능이 내려가는 단점도 있어요.

 

일단, 종료 조건을 한번 넣어 볼까요..

뭐, for문처럼 조건을 내부에 넣는 것도 방법이에요. 매개변수를 이걸로 쓰는 방법도 있고요.

흠, printf문 안에 횟수를 넣어서 시행을 알아보도록 합시다.

#include <stdio.h>

void apple(int a);

int main(void)
{
	apple(1);

	return 0;
}

void apple(int a)
{
	printf("%d apple\n", a);
	if (a == 20)
		return;
	apple(a + 1);
}

이렇게 고치면 아주 완벽해요.

 

1 apple
2 apple
3 apple
4 apple
5 apple
6 apple
7 apple
8 apple
9 apple
10 apple
11 apple
12 apple
13 apple
14 apple
15 apple
16 apple
17 apple
18 apple
19 apple
20 apple

흠, 여기까지 왔으면 재귀문을 반복문(while, for) 등으로 바꿔먹어도 될 것 같습니다.

 

한번 다음과 같이 프로그래밍해보세요.

#include <stdio.h>

void apple(int a);

int main(void)
{
	apple(1);

	return 0;
}

void apple(int a)
{
	printf("%d apple\n", a);
	if (a == 10)
		return;
	apple(a + 1);
	printf("%d Banana\n", a);
}

아마 저 뒤에 printf("%d Banana\n", a); 는 실행이 안 될 겁니다. 

apple만 10번 시행하겠죠. 안 그래요?

한번 돌려봅시다.

1 apple
2 apple
3 apple
4 apple
5 apple
6 apple
7 apple
8 apple
9 apple
10 apple
9 Banana
8 Banana
7 Banana
6 Banana
5 Banana
4 Banana
3 Banana
2 Banana
1 Banana

..?

 

왜이런담?

 

이전에도 말했지만, 재귀 함수는 계속 자기 자신을 호출해요.

 

저 상황에서 return이 되면 더 이상 함수가 자기 자신을 호출하지 않지만... 재귀함수는 자기 자신을 return 했기 때문에 실제로는

10 apple에 해당하는 재귀문만 빠져나온 것이고, 실제로는 9apple에 해당하는 재귀문에 있는 상태에요.

그리고 9apple에 해당하는 return으로 돌아온 뒤 appple(a+1)을 처리하지만, if문 밖이라 별 의미는 없고 9 banana가 출력된 후

함수가 종료되어 이전에 해당하는 8apple로 돌아오고.. 반복이죠.

 

재귀함수는 반복문과 다르게 자신을 호출해서 스텍하는 걸 알아두세요!

이걸 응용해서 뒤집기(reverse)나 계산 누적, 트리 탐색같은걸 할 수도 있는데..

 

이해가 안 되신다면 이걸 보면 됩니다.

apple(1)
{
	printf("1 apple");
	retrun;
	apple(2)
	{
		printf("2 apple");
		retrun;
		apple(3)
		{
			printf("3 apple");
			retrun;
			apple(10)
			{
         		   	......
				printf("10 apple");
				retrun;
			}
      	 		......
			printf("3 banana");
		}
		printf("2 banana");
	}
	printf("1 banana");
}

 

728x90

'프로그래밍 > C' 카테고리의 다른 글

함수의 작성과 사용  (0) 2025.04.23
연산자 - 예제 모음  (0) 2025.04.20
반복문 - 예제 모음  (0) 2025.04.18
선택문 - 예제 모음  (0) 2025.04.18
변수와 데이터 입력 - 예제 모음  (0) 2025.04.18