cyphen156

Chapter4 함수Ⅰ 본문

프로그래밍/C언어

Chapter4 함수Ⅰ

cyphen156 2023. 2. 9. 15:55

주의

주인장의 개인적 사견이 매우 많이 들어가 있습니다.

저도 공부하고 있는 입장이므로 피드백 환영합니다.
함수(function)는 뭘까?

함수는 특정한 기능을 수행하기 위해 호출을 받으면 무언가(인자 = 매개변수 = 파라미터/parameters)를 전달받아 호출자에게 결과를 돌려주는 명령문들의 집합체라고합니다.

단순하게 생각하면 수학에서의 함수 f(x) : y = 2x + 4라고 할 때,  f(x)는 함수명, y는 return되는 결과물, 2(x) + 4는 함수를 호출했을때 실행되는 명령문, x는 함수로 전달되는 인자값이라고 생각하면 됩니다.

함수는 왜 쓰는가?

처음에는 궂이 함수를 따로 만들어서 작업을 처리할 필요 없이 main에서 처리하면 편하고 쉽지 않겟느냐?라는 의문이 들 수 있습니다. 지금은 코드가 100줄 안밖으로 짧게 작성할 수 있지만 프로그램을 만들때 한개의 소스 코드 안에 수 천~ 수 만줄의 코드가 들어가게 될 수 있고, 같은 기능을 수행하는 코드를 여러번 작성하게 될 수도 있습니다. 또한 코드가 길어지면 오류가 발생하는 부분을 찾아내는것 자체가 힘들어 집니다. 그래서 이런 문제점들 (코드의 중복, 가독성, 가시성)을 최소화 하고 문제가 발생했을때 수정하는 작업(유지 보수)를 편하게 하기 위해 사람들은 함수라는 것을 만들어서 사용하기 시작했습니다. 

함수를 사용했을 때의 장점

  • 중복되는 코드들을 짧은 코드를 여러개로 쪼개어 작성하여 유지 보수성을 극대화 할 수 있다.
    -> 객체지향에서의 모듈식 프로그래밍의 기원이 된다.
  • 함수를 호출할 때 인자값은 copy & write되어 함수 내부의 지역변수가 생성되기 때문에 main함수의 자료 값들(원본데이)을 보호할 수 있다. 
    -> 저는 [각주:1]람다식(화살표 함수)을 사용하는 이유가 여기에 있다고 생각합니다.

좀 더 나아가면 함수와 구조체라는 것은 객체지향프로그래밍(OOP)으로 발전하였고, 이제는 함수형 프로그래밍이라는 패러다임까지 등장하고 있는데 이에 대한 생각은 나중에 풀어보도록 하겠습니다.

함수의 사용법

  1. 함수를 정의한다.
  2. 함수를 호출한다, 필요하다면 호출할때 매개변수를 전달해준다.
  3. 결과물을 호출자가 전달받는다.

다음 코드를 보면 main함수 외부에 add라는 함수를 정의하였다.

코드를 실행하면 main함수는 print문과 scanf문을 실행한 뒤 sum이라는 변수에 add()함수를 호출하여 매개변수로 first와 second를 전달하고 대기한다. 

add함수의 실행이 끝나면 결과값 total을 main함수에 돌려주고(return), sum에 대입한 뒤 남은 명령문들을 수행한다. 

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

//  인자(매개변수) 두개(first, second)를 (f, s)에 전달받아 
//  int형 변수 total을 결괏값으로 돌려주는 함수 add(함수명)
    int add(int f, int s) {
        int total;
        total = f + s;
        return total;
    }
    
int main() {
    int first, second, sum;
    printf("Enter two input integers.\n");
    scanf("%d %d", &first, &second);
    sum = add(first, second);
    printf("The result is %d.\n", sum);
    return 0;
}

여기에서 main함수는 함수를 호출하는 주체이기 때문에 호출자이고, add()함수는 호출 당하는 대상이기 때문에 피호출자입니다. main함수 내부에 있는 first와 second는 실제 사용되는 변수이기 때문에 실질 인자/인자라고 하고, add()함수 내부에서 사용되는 f와 s는 형식 인자/매개변수라고 합니다.

함수의 실행 순서

함수는 호출될 때 스택의 형태로 호출됩니다. 마치 책으로 탑을 쌓듯이 순서대로 쌓여서 위에 쌓인 것부터 실행하면서 치워나갑니다.  

스택(Stack)

다음의 코드는 스택의 형태를 보여주기 위한 코드입니다. 비주얼 스튜디오에서 각 함수를 호출할 때 중단점을 찍어서 디버깅을 해보시면 각 함수가 호출되고 결과를 return받을 때 어떤 작업이 수행되는지 볼 수 있습니다.

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

int square(int m) {
	return m * m;
}

int square_add(int f, int s) {
	int total;
	total = square(f) + square(s);
	return total;
}
int main() {
	int first, second, sum;
	printf("Enter two integers.\n");
	scanf("%d %d", &first, &second);
	sum = square_add(first, second);
	printf("The result is %d.\n", sum);
	return 0;
}

다음과 같이 main함수가 square_add(first, second)를 호출하고, square_add()는 다시 square(f), square(s)를 호출합니다. 그리고 역순으로 작업을 처리(square(s) -> square(f) -> square_add(first, second) -> main)해나갑니다.

함수를 사용할때 주의점

  • 반드시 리턴타입을 맞추어줘야 합니다. 이 때 리턴타입이란 함수명 앞의 int / void / float 등 자료형을 의미하고, return total;의 자료형이 동일해야 함을 의미합니다 ex) float add()라고 함수를 정의했다면 return (float)result;가 되어야 함을 말함
  • C언어에서 리턴되는 자료의 값은 반드시 하나여야만 합니다. 이것이 싫다면 구조체를 사용하던지 포인터를 통해 인자를 변형시켜야 합니다.
  • C언어는 대부분의 컴파일러가 [각주:2]원 패스 컴파일러이기 때문에 반드시 사용하려는 함수가 미리 #include되거나 선언되어 있어야 합니다.
  • 아무런 값도 반환하지 않는 함수가 있을 수 있습니다. 함수를 void로 선언하면 return문을 사용하여 결과를 돌려주지 않아도 됩니다.
  • 어떤 함수던지 중간에 return문을 수행하면 즉시 해당 함수를 종료하고 호출자로 돌아갑니다.

이번챕터에서는 함수에 대해 대략적인 것을 알아보았는데요 좀 더 자세한 내용은 반복문과 조건문에 대해 공부한 뒤 다루겠습니다.

//모든 예제 소스는 한빛 미디어홈페이지에서 찾으실 수 있습니다.

IT CookBook, 전공자를 위한 C 언어 프로그래밍 (hanbit.co.kr)

또는 cyphen156/Work-space: Studying (github.com)에서 찾으실 수 있습니다.

 

 

 

 

 

  1. 람다식 : 함수를 따로 만들어서 사용하지 않고 즉석에서 만들어쓰는 임시(익명) 함수 [본문으로]
  2. one path compiler : 컴파일을 수행할 때 소스코드를 단 한번만 읽고 번여갛는 컴파일러 [본문으로]

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

Chapter5 조건문 : If와 Switch  (0) 2023.06.02
Chapter4 과제  (0) 2023.02.10
Chapter3 과제  (0) 2023.02.03
Chapter3 변수와 상수, 대입문과 연산  (0) 2023.02.01
Chapter2 과제  (0) 2023.01.05