본문 바로가기
혼공학습단 C

C언어 W4(7강 함수)

by 알래스카코코넛 2023. 7. 24.
반응형

*본 포스팅은 한빛미디어의 '혼자공부하는 C언어(1판)'기준으로 작성되었습니다.

Chapter7. 함수 

7-1. 함수의 작성과 사용 

함수의 정의는 '기능을 수행하는 코드 단위'다. 실생활을 예로 들면, '심부름'이라는 함수가 있다고 하자. 이 심부름을 이루는 작업은 

  • 구매 리스트 받기
  • 가게를 찾아가기
  • 물건 구매하기
  • 집으로 돌아가기

로 이루어져 있다. 따라서 의사코드로 나타내면, 

int simbooroom(char list)
{
    구매 목록(list) 받기
    가게 찾아가기
    목록(list)에 맞게 구매하기
    집에 돌아가기
    return list
}

이런 느낌이다. '심부름'이라는 함수를 list만 다르게 대입하여 주면, 매번 printf, scanf 등을 사용해서 전체 코드가 길어질 필요 없이 명령을 재사용할 수 있다. 

 

우선 함수를 만드는 위치는 main 밖에 만든다. main또한 함수고, 일단은 다른 함수와 대등한 위치에 있기 때문에 main안에 함수를 작성하게 되면 함수안에 함수를 넣지 않는다는 규칙에 위배된다. 

 

함수의 형식은 다음과 같다:

1. 반환형: 이 함수의 결과가 어떤 자료형인지를 알려준다. 이게 사실 생소한 개념이고 특히 파이썬과 같이 최근에 개발된 코드를 사용하는 사람이면 의아할 수 있는데, C는 정말 프로그래밍 언어의 조상님이다. 처어어어음 단계부터 프로그래머가  이게 뭔지 알려줘야 한다. 눈치껏 '아 이건 정수형이겠죠?'같은건 없다. 만두를 빚는다고 치면 파이썬은 만두피랑 만두속을 마트에 있는걸 사와서 그걸 조립하는 느낌이면, C는 밀가루로 만두피 만들기부터 시작한다. 이거 데이터형 없는데? 라고 생각하면 void를 사용하면 된다. 

 

2. 함수명: 이 함수의 이름이 무엇인지를 나타낸다

 

3. 매개변수: 함수가 처리할 데이터다. 0개, 1개, 2개.... 여러 종류의 가짓수를 받을 수 있고, 반환형과 자료형이 같을 필요는 없다. 이 매개변수가 약간 헷깔릴 수 있는데, 우리가 익숙한 수학으로 치면 f(x) = x+1으로 예를 들어보자. x가 매개변수고, 이 x에 1,2,3을 대입하면 2,3,4를 출력한다. 즉, '사용자가 지정하는 값이 들어갈 자리'가 매개변수다. 

 

함수의 호출 

 

학교 과제로 '함수를 만들고, 그 함수를 호출해주세요~'라고 교수님이 말씀하신 적이 있는데, 이게 무슨 의미인지 몰랐던 적이 있다. 함수 호출이 말이 거창해서 그렇지, 실제로 하는건 간단하다. main함수 안에서 그 함수를 언급하는게 함수의 호출이다. 

예:

#include <stdio.h>
int add(int x, int y){
    int result;
    result = x+y;
    return result;
}

int main(){
    
    int ReturnedValue;
    ReturnedValue = add(3,4)//이게 함수의 호출 
    printf("반환된 값:%d\n", ReturnedValue);
    
    return 0;
}

여기서 main함수 안에 add(3,4)가 add함수를 호출했다는 의미다. 

 

함수의 반환 

왜 함수 안에 return result;가 있는지 의아할 수도 있는데, 이게 함수의 반환에 사용되는 밑바탕이다. 함수의 반환이란, 함수가 실행을 끝내고 값을 반환할 때 사용하는 것으로 '얘가 함수의 결과물이야!'를 나타낸다.  동시에, '이 함수의 작동이 끝났으니 다시 메인함수로 돌아가(return)!'도 의미한다. 

 

함수의 선언

앞에서 '함수는 main 밖에 만든다'라고 했는데, 함수 내용이 main아래에 있으면 위에서부터 읽는 C언어의 특성 상 main함수에서 그 함수를 작동시킬 수 없다. 그러면 무조건 함수가 main 위에 있어야 하는가? 그건 아니다. 일단 위에 '이런 함수가 있습니다'를 언급해두고, main함수에서 그 함수를 사용하면 자동으로 아래 부분에 해당 함수를 찾아준다. 이렇게 위에 언급해 두는걸 함수의 선언이라 한다. 

그냥 위에 적어두면 되는걸 왜 굳이 선언을 하나? 싶겠지만, 두 가지 이유가 있다.

  1. 함수 반환값과 매개변수의 자료형을 확인하기 쉽다.
  2. 함수의 호출 형식에 문제가 없는지 알 수 있다.

7-2. 여러가지 함수 유형 

1. 매개변수에 따라 달라지는 함수 

위에 매개변수 부분에서 '매개변수: 함수가 처리할 데이터다. 0개, 1개, 2개.... 여러 종류의 가짓수를 받을 수 있고,'라고 했는데, 말 그대로 함수가 어떤 기능을 하냐에 따라 매개변수의 가짓수는 달라진다. 예를 들어, '창틀닦이'라는 함수는 1명이 필요하면 받는 매개변수가 한 사람의 이름이고, '줄 맞추기'가 2명이 필요하면 매개변수는 2개, '짐 옮기기'가 3명이 필요하다면 매개변수가 3개가 된다. 

 

2. 반환값이 없는 함수 

단순히 화면에 출력하고, 특정 값을 main함수에서 사용하지 않는다면 반환값이 없어도 된다. 위에서 언급했듯, main함수에서 다른 함수의 결과값이 필요하면 '얘가 함수의 결과물이야'라고 알려줄 필요가 있는데, 그 때 사용하는게 반환값이 있는 함수다. 따라서 굳이 함수의 결과물을 알 필요 없이, 화면에 출력만 한다면 반환값 return 어쩌구가 없어도 된다. 

 

반환값이 없는 함수 예시 - 단순 출력만 한다. 

 

#include <stdio.h>

void printing(char ch); //함수 선언 

int main() {
    char word;
    printf("출력할 단어를 입력하세요:");
    scanf("%c", &word);
    printing(word);
    
    return 0;
}

void printing(char ch){
    printf("입력한 단어를 출력합니다: %c", ch);
}

3. 재귀호출 함수

영어에서 재귀대명사를 들어본 적이 있으면 더 이해하기 쉽다. 재귀대명사는 myself, themselves 처럼 본인을 언급하는 것으로, 재귀호출 함수도 자기 자신을 언급한다는 뜻이다. 지금은 간단한 예시만 살펴보지만, 심화되면 교수님들의 단골 문제 중 하나다. 특히 if와 while을 이용해서 피보나치 수열을 재귀 방식으로 만드는 문제가 유명하니 잘 알아두자. 

참고로 난 그 문제 틀렸다....

 

재귀함수 예시: 

#include <stdio.h>

void Recursive(int cnt){
    printf("Hello, World!\n");
    
    if (cnt >=3)
        return;
        
    Recursive(cnt+1);//Recursive함수 안에 Recursive함수가 있다. 
}

int main(void){

    Recursive(0);
    
    return 0;
}
//결과:
//Hello, World!
//Hello, World!
//Hello, World!
//Hello, World!

이번주 기본 미션이었던 함수의 유형을 정리하여 공유하기....는 위에 7-2. 여러가지 함수 유형 부분으로 성공했다.

야호!

추가미션 p.198 7-5: apple 출력하고 종료한 화면 캡쳐하기, 왜 무한대로 출력되지 않는 이유에 대해 생각하고 정리해보기

 

#include <stdio.h>

void fruit(void);//함수 선언 

int main(void) { 
	fruit();   //함수 호출 

	return 0;
}
void fruit(void) {  //재귀 함수 정의 
	printf("apple\n");
	fruit(); //재귀 
}

코드: -10737....만 봐도 정상적인 종료는 아니다.

재귀함수로 무한히 출력되도록 했음에도 무한대로 출력되지 않는 이유는 프로그램에 할당된 메모리를 모두 소모했기 때문이다. 따라서 반드시 중간에 멈추는 조건을 달아줘야 하며, 그렇지 않으면 이거 왜이래 으아아아 하다가 컴퓨터에 과부하가 걸릴 수 있다. 

이상으로 이번 주 미션도 끝났다. 어느새 벌써 반 이상을 왔으니 웬만한 일이 아니면 완주할 수 있을 것 같다!

 

 

반응형

'혼공학습단 C' 카테고리의 다른 글

C언어 W6(9강 포인터)  (0) 2023.08.16
C언어 W5(8강 배열)  (0) 2023.08.08
C언어 W3(5 ~ 6강)  (0) 2023.07.20
C언어 W2-2(4강)  (0) 2023.07.13
C언어 W2-1 (3강)  (0) 2023.07.11