19. 함수 사용하기

  • 59 minutes to read

함수는 코드의 재사용성을 높이기 위해 특정 작업을 수행하는 코드 블록입니다. 이번 강의에서는 함수를 활용하여 반복되는 코드를 효율적으로 관리하는 방법을 알아보겠습니다.

> // 함수(Function): 반복해서 사용하도록 만들어진 하나 이상의 문을 포함하는 코드 단위(블록)
  • 함수는 하나 이상의 문(statement)을 포함하는 코드 블록으로, 반복적으로 사용할 수 있습니다.
  • 함수는 특정 작업을 수행하는 코드 블록이며, 이름, 매개변수(parameters), 본문(body), 그리고 반환문(return statement)으로 구성됩니다.

함수 소개

프로그래밍을 하다 보면 종종 동일한 유형의 코드가 반복됩니다. 이런 코드를 매번 작성하는 것은 비효율적이며 오류가 발생할 가능성도 높습니다. 함수를 사용하면 이런 문제를 해결할 수 있습니다.

함수는 특정 작업을 수행하는 코드 블록으로, 재사용을 목적으로 합니다. 함수는 입력값을 받아 처리하고 결과값을 반환하는 코드입니다. 함수는 프로그램 내에서 독립적으로 작동하는 모듈 또는 단위로 간주됩니다. 예를 들어, C언어에서 main 함수는 프로그램의 시작점을 나타내는 특수한 함수이며, printf()는 콘솔에 출력하는 함수입니다. 참고로, 과거 프로그래밍 문헌에서는 함수를 "루틴(Routine)", "서브 프로시저(Sub Procedure)", 또는 "서브 루틴(Sub Routine)" 등으로도 표현했습니다.

입력, 처리, 출력

함수는 일련의 작업들을 수행하는데 중심적인 역할을 하는데, 특히 입력을 받아 처리하고, 결과를 출력하는 과정에 있어서 중요합니다. 아래 그림은 이 과정을 간략히 도식화한 것으로, 함수가 처리 과정을 담당하는 이름이 있는 코드 블록으로 구성되어 있음을 보여줍니다.

그림: 입력, 처리, 출력

입력, 처리, 출력

여기서 입력은 함수가 처리할 데이터를 제공하는 단계, 처리는 이 데이터를 사용하여 특정 작업을 수행하는 단계, 그리고 출력은 처리된 결과를 반환하는 단계로 구성됩니다. 함수를 통해 이 세 가지 주요 단계를 효율적으로 관리할 수 있습니다. 함수는 다음 그림의 처리를 담당하는 부분을 따로 이름있는 코드 블록으로 지정하는걸 말합니다.

함수의 종류: 내장 함수와 사용자 정의 함수

내장 함수(built-in function)는 프로그래밍 언어가 제공하는 미리 정의된 함수로, 문자열 처리, 날짜 및 시간 계산, 수학 연산, 형 변환 등 다양한 기능을 포함합니다. 내장 함수들은 종종 API(Application Programming Interface) 또는 라이브러리(library)의 일부로 제공됩니다.

반면, 사용자 정의 함수(user-defined function)는 프로그래머가 필요에 따라 직접 생성하여 사용하는 함수입니다.

함수 정의하고 사용하기

함수를 생성하는 것을 "정의(define)"라고 하며, 만들어진 함수를 실행하는 것을 "호출(call)"이라고 합니다. 함수를 정의하고 호출하는 데는 소괄호가 사용됩니다.

기본적인 함수 정의 형태는 다음과 같습니다:

함수이름()
{
    // 함수 본문
}

함수를 호출하는 방법은 다음과 같이 세 가지 형태로 표현할 수 있습니다:

함수이름();
함수이름(매개변수);
결과값 = 함수이름(매개변수);

함수를 만들고 사용하는 내용을 그림으로 표현하면 다음과 같습니다.

그림: 함수 정의 후 호출

함수 정의 후 호출

C언어에서는 사용자 정의 함수를 main 함수 앞에 정의하는 것이 일반적입니다. 하지만 함수 원형(prototype)을 사용하면 main 함수 뒤에 함수를 정의할 수도 있습니다.

main 함수에서 sub 이름으로 만들어진 함수를 호출하는 내용을 그림으로 표현하면 다음과 같습니다.

그림: 함수 실행 순서

함수 실행 순서

함수 만들고 호출하여 사용하기

이번에는 함수의 가장 기본적인 모양을 만들고 사용해보겠습니다. 참고로 다음 코드의 Show() 메서드는 Main() 메서드 밑에 코드를 작성해도 상관 없습니다.

코드: FunctionDemo.cs

// FunctionDemo.cs
using System;

class FunctionDemo
{
    //[1] Show 메서드(함수)
    static void Show()
    {
        Console.WriteLine("Hello World");
    }

    // Main 메서드(함수)
    static void Main()
    {
        Show(); //[2] 호출
    }
}
Hello World

위 코드는 [1]번 코드 영역에 Show() 이름의 함수를 만들고 이를 Main() 메서드의 [2]번에서 호출해 보는 내용입니다. Show() 함수와 같은 형태를 가장 간단한 형태의 함수로 매개 변수(Parameter)도 없고 반환값(Return Value)도 없는 형태입니다. 잠시 후에 매개 변수와 반환값에 대해 알아봅니다.

함수 선언(Function declaration)

함수를 만드는 작업을 함수 선언이라고 합니다.

함수 만들고 반복 사용하기

함수를 만드는 목적 중 하나는 반복 사용에 있습니다. 함수를 만들고 여러 번 호출해서 사용하는 방법을 알아보겠습니다. main 함수를 포함해서 최소한의 코드로 표현했습니다.

코드: function_call.c

//[?] 함수(Function): 반복하여 사용하도록 하나의 이름으로 만들어 놓은 코드의 집합
#include <stdio.h>

//[1] 함수 만들기(정의, 선언)
hi()
{
    puts("안녕하세요.");
}

int main(void)
{
    //[2] 함수 사용하기(호출): 여러 번 호출
    hi(); hi(); hi();

    return 0;
}
안녕하세요.
안녕하세요.
안녕하세요.

이번 코드에서는 hi 이름으로 함수를 만들고 이를 main 함수에서 3번 호출해서 사용하는 내용입니다. C 언어 프로그래밍에서 함수 선언은 함수를 호출하기에 앞서서 코드가 위치해야합니다. 함수의 첫번째 사용 목적 중 하나는 반복 사용에 있습니다. 한번 코드로 만들어 놓은 함수를 여러 번 호출하여 사용할 수 있습니다.

매개 변수와 반환값의 이해

함수는 같은 기능을 반복해서 사용하는 것 이상의 역할을 수행할 수 있습니다. 호출될 때마다 조금씩 다른 동작을 하도록 매개 변수를 사용해 함수를 구성할 수 있습니다. 함수에게 전달하는 값은 문자열, 숫자 등 다양한 데이터 타입이 될 수 있으며, 이러한 값을 인수(Argument), 인자, 파라미터(Parameter), 매개 변수 등으로 칭합니다. 이러한 용어들은 C 언어에서는 같은 개념으로 사용됩니다.

함수의 매개 변수 선언

함수에 정보를 전달하는 데이터인 매개 변수는 콤마(,)를 사용하여 여러 개를 지정할 수 있습니다. 이를 통해 함수의 유연성을 크게 확장할 수 있습니다.

매개 변수가 없는 함수

매개 변수와 반환값이 없는 가장 단순한 형태의 함수는 함수 이름 뒤에 오는 괄호 안에 아무런 값도 지정하지 않는 형태입니다. 예를 들어, 우리가 이전에 만든 hi 함수가 이에 해당합니다.

매개 변수가 있는 함수

한 개 이상의 인자값을 전달받아 특정 작업을 수행하는 함수를 의미합니다. 이러한 함수는 정수형, 실수형, 문자형, 문자열형 등 다양한 데이터 타입의 인자값을 처리할 수 있습니다.

반환값이 있는 함수

함수가 처리한 결과를 호출한 곳으로 돌려보내고자 할 때 return 키워드를 사용합니다. 반환값이 있는 함수는 함수(Function)라고도 하며, 반대로 반환값이 없는 함수는 서브 프로시저(Sub Procedure)라고도 합니다.

매개 변수가 있는 함수 예시

매개 변수를 가진 함수의 사용 예를 통해 보다 구체적으로 이해해 보겠습니다.

코드: function_parameter.c

#include <stdio.h>

// 매개 변수가 있는 함수
void show_message(char* message)
{
    puts(message); // 넘어온 매개 변수의 값을 출력
}

int main(void)
{
    show_message("매개 변수"); // "매개 변수" 문자열을 show_message 함수로 전달
    show_message("Parameter"); // "Parameter" 문자열을 show_message 함수로 전달

    return 0;
}

출력 결과

매개 변수
Parameter

이 예제에서 show_message(char* message) 함수는 문자열을 매개 변수로 받아 출력합니다. 함수 호출 시, 정의된 매개 변수와 동일한 데이터 타입의 값을 전달해야 하며, 매개 변수는 콤마를 사용해 여러 개를 지정할 수 있습니다. 이를 통해 함수는 다양한 입력에 따라 유연하게 동작할 수 있습니다.

반환값이 있는 함수

함수의 주요 특징 중 하나는 반환값입니다. 이는 함수가 작업을 완료한 후 그 결과를 호출한 곳으로 다시 보내는 것을 의미합니다. 반환되는 값은 C 언어가 지원하는 모든 데이터 타입이 될 수 있습니다. 반환값이 있는 함수를 정의할 때는, 반환값이 없음을 의미하는 void 키워드 대신에 반환되는 데이터 타입을 명시하면 됩니다. 반환값이 없는 함수는 void를 사용하거나 생략할 수 있습니다. 따라서, 우리가 지금까지 사용해온 C 언어의 main 함수는 반환값을 생략하거나 void 또는 int로 설정할 수 있습니다.

1. 문자열 반환값이 있는 함수 만들기 및 사용

문자열 데이터를 반환하는 함수를 만들어 사용해보겠습니다. 문자열 리터럴을 반환할 수 있는 문자열 데이터 타입으로는 char*를 사용합니다.

코드: return_value.c

// 반환값이 있는 함수 만들고 호출하기
#include <stdio.h>

char* get_string()
{
    return "반환값(Return Value)"; // return 키워드를 사용하여 문자열 반환
}

int main(void)
{
    // get_string 함수를 호출하고 반환된 값을 return_value 변수에 저장
    char* return_value = get_string();
    printf("%s\n", return_value);

    return 0;
}
반환값(Return Value)

get_string 함수를 호출하면, return 키워드를 통해 "반환값(Return Value)" 문자열이 호출한 곳으로 반환됩니다. 이 반환된 문자열은 return_value 변수에 저장되어 main 함수에서 사용됩니다.

2. 정수형 반환값이 있는 함수 만들기 및 사용

이제는 int 형식의 반환값이 있는 함수를 사용해보겠습니다.

코드: function_return_value.c

// 반환값이 있는 함수
#include <stdio.h>

int SquareFunction(int x)   // 입력: 매개 변수가 있음
{
    int r = x * x;          // 처리: 함수의 본문
    return r;               // 출력: 반환값이 있음
}

int main(void)
{
    int r = SquareFunction(2); // 함수를 호출하고 반환값을 받음
    printf("%d\n", r); // 출력: 4

    return 0;
}
4

x라는 매개 변수로 정수형 데이터를 받아, 그 값을 제곱한 결과를 main 함수로 반환합니다. 이는 입력(Input), 처리(Process), 출력(Output)을 포함하는 전형적인 함수의 예로, 이러한 스타일의 함수는 앞으로도 계속 사용될 것입니다.

두 실수의 합 계산 함수

아래의 코드는 두 개의 실수를 인자로 받아 그 합을 계산하고, 그 결과를 반환하는 함수를 보여줍니다.

코드: get_sum_two_number.c, GetSumTwoNumber.c

#include <stdio.h>

// 두 실수의 합을 계산하는 함수
double get_sum(double x, double y)
{
    double result = x + y;
    return result;
}

int main(void)
{
    double sum = get_sum(3.0, 0.14); // 함수 호출 및 결과 저장
    printf("%lf\n", sum); // 출력: 3.14

    return 0;
}
3.140000

get_sum() 함수는 double 타입의 두 인자를 받아, 이들의 합을 계산한 다음 그 결과를 반환합니다. 이때, main 함수에서는 이 함수를 호출하고 반환된 값을 출력하여 사용자에게 결과를 보여줍니다.

반환값이 있는 함수 반복 설명

반환값이 있는 함수는 C 언어에서 가장 기본적인 개념 중 하나입니다. 이번 아티클에서는 C 언어에서 반환값이 있는 함수의 개념과 사용법에 대해 알아보겠습니다. 또한, 예시 코드를 통해 어떻게 반환값이 있는 함수를 작성하고 호출하는지 살펴보겠습니다.

반환값이 있는 함수란?

반환값이 있는 함수는, 함수가 실행된 결과 값을 반환하는 함수를 의미합니다. 이러한 함수는 함수의 반환형에 따라, 반환할 값의 데이터 타입과 형식을 명시할 수 있습니다. 반환형으로는 int, float, double, char 등의 데이터 타입이 사용됩니다.

아래는 반환값이 있는 함수의 형식입니다.

<반환형> <함수명>(<매개변수>) {
  // 실행 코드
  return <반환값>;
}

반환값이 있는 함수는 다음과 같은 형식으로 작성됩니다. 함수명, 매개변수, 반환형 등의 구성 요소는 반환값이 없는 함수와 동일합니다. 하지만 함수 내부에서 계산된 결과 값을 return 키워드를 사용하여 반환하는 것이 반환값이 있는 함수의 특징입니다.

반환값이 있는 함수 예시

다음은 반환값이 있는 함수의 예시 코드입니다.

#include <stdio.h>

int sum(int num1, int num2) {
  return num1 + num2;
}

int main(void) {
  int result;

  result = sum(5, 5);
  printf("5 + 5 = %d\n", result);

  return 0;
}

위 코드에서는 반환값이 있는 함수 sum을 정의하고 호출하고 있습니다. sum 함수는 두 개의 정수 값을 입력받아 덧셈을 계산하고, 계산된 결과 값을 반환합니다.

sum 함수의 반환형은 int이므로, 반환할 값의 데이터 타입과 형식을 명시해주어야 합니다. 반환값은 return 키워드를 사용하여 반환하며, 반환되는 값은 sum 함수의 반환형과 일치해야 합니다.

main 함수에서는 sum 함수를 호출하고, 반환된 값을 result 변수에 저장하고 출력하는 예시 코드입니다.

전체 코드와 실행 결과는 다음과 같습니다.

코드: function_return_value_sum.c

#include <stdio.h>

void hi(void) {
    printf("안녕\n");
}

void hello(char message[]) {
    printf("%s\n", message);
}

int sum(int num1, int num2) {
    return num1 + num2;
}

int main(void) {
    int result;

    // [1] 매개변수도 없고 반환값도 없는 경우
    hi();
    hi();

    // [2] 매개변수는 있고 반환값이 없는 경우
    hello("안녕하세요.");
    hello("반갑습니다.");

    // [3] 매개변수도 있고 반환값도 있는 경우
    result = sum(5, 5);
    printf("%d\n", result);

    return 0;
}
안녕
안녕
안녕하세요.
반갑습니다.
10

결론

반환값이 있는 함수는 C 언어에서 매우 중요한 개념 중 하나입니다. 반환값이 있는 함수를 사용하면 함수의 실행 결과 값을 다른 변수에 저장하거나, 다른 함수의 인자 값으로 사용할 수 있습니다. 함수의 반환형과 일치하는 데이터 타입의 값을 반환하며, return 키워드를 사용하여 반환합니다. 반환값이 있는 함수는 C 언어에서 매우 자주 사용되는 개념이므로, 반드시 익혀두어야 합니다.

19.11 함수 원형

함수 선언은 반드시 main 함수 앞에 위치해야 합니다. 하지만, 함수 원형(prototype)을 사용하여 함수에 대한 시그니처를 main 함수 앞에 위치하고 실제 함수 본문은 main 함수 뒤에 올 수 있습니다.

다음 코드는 say 함수가 main 함수 뒤에 오는 형태라서 say 함수에 대한 정보를 알 수가 없어서 에러가 발생합니다.

코드: function_prototype.c

에러 발생 코드

#include <stdio.h>

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

void say(void)
{
    printf("안녕하세요.\n");
}

사용자 정의 함수가 main 함수 앞에 오지 않는 경우에는 반드시 사용자 정의 함수의 함수 시그니처를 main 함수 앞에 선언해 주어야 합니다. 이것을 함수 원형이라고 합니다. 함수 원형을 선언 후 main 함수 뒤에서 함수 본문을 정의해주면 정상적으로 함수 호출이 이루어집니다.

코드: function_prototype.c

정상 실행 코드

#include <stdio.h>

//[1] 함수 원형 선언
void say();

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

//[2] 함수 본문 정의
void say(void)
{
    printf("안녕하세요.\n");
}
안녕하세요.

C 언어에서는 반드시 main 함수 앞에 함수 원형 또는 함수 본문에 대한 정의가 와야 합니다. 다만, 강의에서는 특별한 경우가 아니면 지면을 아끼기 위해서 함수 원형 보다는 함수 내용이 main 함수 앞쪽에 위치할 예정입니다.

19.12. 함수 선언 형식과 관련 용어 정리

이쯤에서 함수(함수) 관련 용어를 정리해 보겠습니다. 앞으로도 계속 다룰 내용이기에 한번 정도 읽고 넘어가도 됩니다. 다음 코드 조각은 main 함수의 가장 자세한 모양입니다.

int main(int argc, char *argv[])
{

    return 0;
}
  • main 함수 선언 형식: 함수는 위 코드와 같은 구조를 가지는데, 함수의 모양은 서로 다른 모습으로 보여질 수 있는데, 이를 함수 시그니처(Signature)라고 부릅니다.
  • void: 함수의 반환 형식이 오는 자리이며 void 키워드는 반환값이 없다는 것을 나타냅니다. 이는 함수 수행 결과 어떤 값을 반환하고자 할 때 반환하고자 하는 데이터의 형식을 말합니다.
  • main: 함수의 이름을 나타내며 함수 이름은 영문 소문자로 시작합니다. 강의에서는 사용자 정의 함수는 영문 대문자로 표현을 많이 합니다.
  • int argc, char *argv[]: 매개 변수(Parameter) 영역이며 함수에 어떤 값을 넘겨주고자 할 때 또는 넘겨받고자 할 때 이를 잠시 보관해 놓는 그릇 역할을 하는 매개체가 되는 변수(배열)를 나타냅니다. 매개 변수는 콤마(,) 기호를 구분으로 0개 이상을 둘 수 있습니다. main 함수에서는 다른 함수와 달리 int argc, char *argv[]를 사용하는데 이는 다른 말로 명령줄 인수(Command Line Argument)라고 하며 예전 운영체제인 도스(DOS) 시절에 주로 사용하던 방식으로, 어떤 실행 파일(EXE 파일)에게 인수(Parameter) 값을 넘겨줄 때, 그 넘겨져 온 인수 값을 가리켜 명령줄 인수(매개 변수)라고 하는데, 이를 프로그램에서 받으려면 C 언어에서는 main 함수의 매개 변수로 받아 사용합니다.
  • 블록({}) : 함수의 실행 범위(Scope)를 나타내며 함수의 블록 내에서 선언된 변수는 해당 함수가 종료되면 소멸됩니다.

19.13. 함수를 사용하여 최대값, 최소값 및 절댓값 구하기

함수를 활용하여 두 수 중 큰 값과 작은 값을 구하고, 주어진 수의 절댓값을 구하는 예제를 살펴보겠습니다. 이 과정에서 매개변수와 반환값을 모두 사용하는 함수의 구현 방법을 알아보겠습니다.

최대값과 최소값 구하기

두 수 중 큰 값을 반환하는 max 함수와 작은 값을 반환하는 min 함수를 정의하여 사용합니다.

코드: max_min_function.c

#include <stdio.h>

// 두 수 중 큰 수를 반환하는 함수
int max(int x, int y) {
    return (x > y) ? x : y; // 3항 연산자 사용
}

// 두 수 중 작은 수를 반환하는 함수
int min(int x, int y) {
    // if-else 문 사용
    if (x < y) {
        return x; // 작은 값 반환
    } else {
        return y; // 또는 y 반환
    }
}

int main(void) {
    printf("큰 값: %d\n", max(3, 5)); // 5
    printf("작은 값: %d\n", min(-3, -5)); // -5

    return 0;
}

출력 결과

큰 값: 5
작은 값: -5

max 함수와 min 함수는 각각 두 정수를 인수로 받아, 큰 수 또는 작은 수를 반환합니다.

절댓값 구하기

절댓값을 구하는 get_abs 함수를 정의하여 사용합니다.

코드: function_abs.c

#include <stdio.h>

// 절댓값을 구하는 함수
int get_abs(int num) {
    return (num < 0) ? -num : num; // 조건 연산자 사용
}

int main(void) {
    int num = -21;
    int abs = get_abs(num);
    printf("%d의 절댓값: %d\n", num, abs);

    return 0;
}

출력 결과

-21의 절댓값: 21

get_abs 함수는 정수를 인수로 받아, 그 수의 절댓값을 반환합니다. 이러한 함수들을 사용하여 프로그래밍 시 발생할 수 있는 다양한 수학적 계산을 손쉽게 처리할 수 있습니다.

절댓값 계산 함수 구현하기

C 언어에서 정수의 절댓값을 쉽게 구할 수 있는 간단한 함수를 만드는 방법을 알아보겠습니다. 이 함수는 정수를 매개변수로 받아 해당 정수가 음수인 경우 양수로 변환하여 반환합니다.

코드: function_absolute_value.c

#include <stdio.h>

// 정수의 절댓값을 반환하는 함수
int calculate_absolute_value(int num)
{
    // 입력받은 정수가 0 또는 양수이면 그대로 반환, 음수이면 양수로 변환하여 반환
    return (num < 0) ? -num : num;
}

int main(void)
{
    // 테스트를 위한 정수 값
    int num = -21;

    // calculate_absolute_value 함수를 사용하여 절댓값 구하기
    int abs_value = calculate_absolute_value(num);

    // 결과 출력
    printf("%d의 절댓값: %d\n", num, abs_value);

    return 0;
}
-21의 절댓값: 21

이 예제에서는 C 언어로 정수의 절댓값을 계산하는 간단한 함수를 만들었습니다. 함수 calculate_absolute_value는 하나의 정수 매개변수를 받습니다. 함수 내부에서 삼항 연산자를 사용하여, 입력 값이 음수인지 확인하고 음수라면 양수로 변환하여 반환합니다. 만약 양수거나 0이라면 입력 값 그대로 반환합니다. 메인 함수에서는 -21이라는 값을 변수 num에 저장하고 calculate_absolute_value 함수를 호출하여 절댓값을 구한 뒤, 화면에 출력합니다. 이를 통해 calculate_absolute_value 함수가 제대로 동작하는 것을 확인할 수 있습니다.

C 언어 사용자 정의 함수에 대한 전체 안내

C 언어에서 사용자 정의 함수에 대해 더 자세히 알아보고 싶으시다면, 아래 링크를 참조하세요. 시간이 되신다면 한번 확인해 보시길 권장합니다.

사용자 정의 함수 전체 설명

19.15. 재귀 함수

재귀 함수는 자기 자신을 호출하는 함수입니다. 이 개념은 함수가 자기 자신을 다시 호출하여 문제를 해결하는 방식을 말합니다.

재귀 함수 사용 예제

재귀 함수의 사용을 이해하기 위해, 반복문으로 구현된 팩토리얼 문제를 재귀 함수를 사용하여 다시 해결해 보겠습니다. 이해를 돕기 위해, "디버거 사용하기"를 참조하여 F10 또는 F11 키를 사용하여 코드를 한 단계씩 진행해보는 것이 좋습니다.

코드: recursion_demo.c

// 재귀 함수 예제
#include <stdio.h>

// 3항 연산자를 이용한 팩토리얼 계산
int fact(int n) {
    return (n > 1) ? n * fact(n - 1) : 1;
}

// 재귀 함수를 이용한 팩토리얼 계산: 특히 트리 데이터 구조 탐색에 유리
int factorial(int n) {
    if (n == 0 || n == 1) {
        return 1;
    }
    return n * factorial(n - 1);
}

// 반복문을 이용한 팩토리얼 계산: 간단한 경우 이 방식이 더 효율적
int factorial_for(int n) {
    int result = 1;
    for (int i = 1; i <= n; i++) {
        result *= i;
    }
    return result;
}

int main(void) {
    printf("%d\n", factorial_for(4)); // 24
    printf("%d\n", factorial(4)); // 24
    printf("%d\n", fact(4)); // 24

    return 0;
}
24
24
24
24

fact 함수와 factorial 함수는 팩토리얼 계산을 위해 자기 자신을 호출합니다. 재귀 호출은 스택 메모리에 저장되어 실행되며, 과도한 재귀 호출은 스택 오버플로 에러를 유발할 수 있습니다. 대량의 데이터 처리 시에는 반복문을 사용하는 것이 더 효율적일 수 있습니다.

n의 m제곱 구하기: 재귀 함수 사용

2의 n제곱을 구하는 프로그램을 재귀 함수를 사용하여 구현해보겠습니다.

코드: RecursionPower.c

// 2의 n제곱 구하기: 재귀 함수 사용
#include <stdio.h>

int MyPower(int num, int cnt) {
    if (cnt == 0) {
        return 1;
    }
    return num * MyPower(num, --cnt);
}

int main(void) {
    printf("%d\n", MyPower(2, 2)); // 4

    return 0;
}
4

MyPower 함수를 통해 2의 2제곱 값을 구할 수 있으며, MyPower(2, 10)과 같이 사용하면 2의 10제곱 값을 구할 수 있습니다.

19.16. 함수 범위(Function Scope): 전역변수와 지역변수

함수 범위는 변수가 선언된 위치에 따라 그 사용 범위가 결정되는 프로그래밍의 기본 개념입니다. C 언어에서는 변수의 선언 위치에 따라 전역 변수(Global Variable)와 지역 변수(Local Variable)로 구분됩니다.

  • 전역 변수: main 함수 밖에서 선언된 변수로, 프로그램 전체에서 접근이 가능하며, 프로그램의 실행이 시작될 때 생성되어 프로그램이 종료될 때까지 유지됩니다.
  • 지역 변수: 특정 함수 내에서 선언된 변수로, 해당 함수 내에서만 접근이 가능하며, 함수의 호출 시 생성되고, 함수의 실행이 종료될 때 소멸됩니다.

이 개념을 보여주는 예제로, 같은 이름의 전역 변수와 지역 변수를 사용하는 상황을 살펴보겠습니다.

코드: FunctionScope.c

#include <stdio.h>

char* message = "전역 변수"; // 전역 변수 선언

void ShowMessage()
{
    char* message = "지역 변수"; // 지역 변수 선언
    printf("%s\n", message);  // 지역 변수 사용
}

int main(void)
{
    ShowMessage(); // "지역 변수" 출력
    printf("%s\n", message); // "전역 변수" 출력

    return 0;
}

출력 결과

지역 변수
전역 변수

위 예제에서 ShowMessage 함수 내의 message 변수는 지역 변수로 선언되었기 때문에, 해당 함수 내에서만 접근이 가능하며, 함수 외부에서는 전역 변수 message가 사용됩니다. 이처럼 같은 이름의 변수가 지역 변수와 전역 변수로 각각 선언되었을 경우, 함수 내부에서는 지역 변수가 우선적으로 사용됩니다. 이는 변수의 범위를 명확히 하여 프로그램의 가독성과 유지보수성을 높이는 데 도움을 줍니다.

명령줄 인수

C 언어에서 명령줄 인수를 통해 프로그램 실행 시 사용자로부터 입력 값을 받아 처리할 수 있습니다.

https://youtu.be/mMXHjMmSgQs

main 함수와 명령줄 인수

C 언어 콘솔 응용 프로그램 프로젝트를 Visual Studio에서 생성하게 되면, main 함수는 int main(int argc, char *argv[])의 형태로 정의되며, 이는 argc로 인수의 개수를, char *argv[]로 인수들을 포함하는 문자열 배열을 매개 변수로 받습니다. argv 배열은 명령줄에서 실행 파일명 뒤에 오는 문자열들을 배열의 형태로 받아 사용하는 기능을 제공합니다. 이러한 문자열들을 명령줄 인수(Command Line Arguments 또는 Command Line Parameters) 혹은 애플리케이션 인수라고 부릅니다. 이는 사용자가 명령줄에서 입력한 매개 변수들을 순서대로 프로그램에 전달할 수 있게 해줍니다. 예를 들어, DOS에서 dir.exe *.* 명령어를 실행할 때, dir.exe 뒤에 오는 *.*가 명령줄 인수에 해당합니다.

코드: ApplicationArgument.c

#include <stdio.h>

int main(int argc, char* argv[])
{
    printf("애플리케이션 인수 개수: %d\n", argc);
    printf("애플리케이션 이름: %s\n", argv[0]);

    return 0; 
}
애플리케이션 인수 개수: 1
애플리케이션 이름: C:\C\C\C\Debug\ApplicationArgument.exe

이 코드와 출력 예시는 main 함수를 통해 애플리케이션 인수를 어떻게 처리할 수 있는지 보여줍니다. 실행 시, argc에는 인수의 개수가, argv[0]에는 실행 파일의 경로가 출력됩니다.

명령줄 인수로 문자열 데이터 2개 입력받기

이번 섹션에서는 main 함수에 명령줄 인수를 사용하여 문자열 데이터를 입력받는 방법을 살펴보겠습니다. 전에는 main 함수에 매개 변수를 사용하지 않았지만, 이번에는 int main(int argc, char* argv[]) 형태로 명령줄 인수를 처리할 수 있는 매개 변수를 사용합니다.

코드: ApplicationArgument.c

#include <stdio.h>

int main(int argc, char* argv[])
{
    printf("argc: %d\n", argc);
    for (int i = 0; i < argc; i++)
    {
        printf("argv[%d]: %s\n", i, argv[i]);
    }

    return 0;
}

이 예제에서는 명령줄 인수를 사용하여 프로그램에 입력을 제공하는 방법을 소개합니다. argc는 입력된 명령줄 인수의 개수를 나타내며, argv 배열은 그 인수들을 문자열 형태로 저장합니다.

실행 방법과 출력 결과

명령줄 인수를 사용하는 방법을 설명하기 위해, C 드라이브의 C 폴더에 CommandLineArgument라는 이름으로 C 언어 프로젝트를 생성했다고 가정합니다.

코드: CommandLineArgument.c

#include <stdio.h>

int main(int argc, char* argv[])
{
    for (int i = 0; i < argc; i++)
    {
        printf("%s\n", argv[i]);
    }

    return 0;
}

이 코드는 argv 배열에 저장된 모든 명령줄 인수를 순회하며 출력합니다. Ctrl + F5를 눌러 프로그램을 실행한 후, 명령 프롬프트에서 다음과 같은 방법으로 프로그램을 실행할 수 있습니다:

  • 단순 실행: 프로그램명만 출력됩니다.
  • 문자열 데이터 두 개 입력: 예를 들어, CommandLineArgument.exe ABC DEF를 실행하면 ABCDEF가 출력됩니다.
  • 공백을 포함한 문자열 데이터 입력: 큰 따옴표를 사용하여 CommandLineArgument.exe "안 녕" "하세요."와 같이 입력하면 공백을 포함한 문자열도 정확히 출력됩니다.

예시 출력

C:\C\CommandLineArgument\Debug>CommandLineArgument.exe
CommandLineArgument.exe

C:\C\CommandLineArgument\Debug>CommandLineArgument.exe ABC DEF
CommandLineArgument.exe
ABC
DEF

C:\C\CommandLineArgument\Debug>CommandLineArgument.exe "안 녕" "하세요."
CommandLineArgument.exe
안 녕
하세요.

이를 통해 명령줄 인수를 통해 프로그램에 다양한 입력 데이터를 제공할 수 있음을 확인할 수 있습니다. 명령줄 인수는 프로그램의 유연성을 높여줄 수 있는 강력한 기능입니다.

19.19. Visual Studio에서 명령줄 인수 설정하기

Visual Studio를 사용할 때, 프로그램에 명령줄 인수를 제공하는 방법은 명령 프롬프트(cmd.exe)를 사용하는 것뿐만 아니라 Visual Studio 자체의 설정을 통해서도 가능합니다. 이를 통해 개발 중인 애플리케이션을 더 쉽게 테스트할 수 있습니다. 명령줄 인수를 Visual Studio 내에서 직접 설정하는 방법을 세 단계로 나누어 설명하겠습니다.

1. 기본 코드 확인

먼저, 명령줄 인수를 사용하여 입력을 받는 기본적인 C 코드를 확인합니다. 코드: CommandLineArgument.c

#include <stdio.h>

int main(int argc, char* argv[])
{
    for (int i = 0; i < argc; i++)
    {
        printf("%s\n", argv[i]);
    }

    return 0;
}

이 코드는 명령줄에서 제공된 인수들을 순회하며 출력합니다.

2. Visual Studio 프로젝트 속성 설정

Visual Studio에서 명령줄 인수를 설정하려면 다음 단계를 따릅니다:

  • CommandLineArgument 프로젝트에 우클릭 후 속성(Properties)을 선택합니다.
  • 속성 창에서 디버그(Debug) 탭을 엽니다.
  • 디버깅(Debugging) 섹션의 명령줄 인수(Command Arguments) 필드에 테스트하고 싶은 문자열을 입력합니다. 예를 들어, "안녕하세요 반갑습니다"라고 입력합니다.

3. 명령줄 인수를 사용하여 프로젝트 실행

이제 설정한 명령줄 인수를 사용하여 프로젝트를 실행합니다. Ctrl + F5를 눌러 프로젝트를 실행하면, argv[1]에 "안녕하세요"가, argv[2]에 "반갑습니다"가 저장되며, 이들이 순차적으로 출력됩니다.

C:\C\CommandLineArgument\Debug\CommandLineArgument.exe
안녕하세요
반갑습니다

이 방법을 통해 Visual Studio 내에서 직접 명령 프롬프트로 이동하지 않고도 명령줄 인수를 통한 테스트를 손쉽게 할 수 있습니다. main 함수는 매개 변수로 문자열 배열을 받아, 이 배열을 통해 명령 프롬프트나 다른 실행 환경에서 프로그램 실행 시 제공된 인수들을 처리합니다. C 언어에서 명령줄 인수는 char* argv[] 형태로 받으며, argv의 이름은 변경 가능합니다. 명령줄 인수는 공백을 기준으로 분리되어 argv[1], argv[2], ... 등의 배열 요소로 저장됩니다. argc 매개 변수는 이 배열의 크기를 나타냅니다.

19.20 퀴즈

  1. 함수의 반환값이 없음을 의미하는 키워드는 무엇인가요?

    • a. int
    • b. void
    • c. static
    • d. not
    • 정답: b
    • 해설: void 키워드는 함수가 반환값을 가지지 않을 때 사용됩니다.
  2. 정수형 매개 변수가 2개이고 반환값이 정수형인 함수를 선언하는 올바른 코드는 무엇인가요?

    • a. float Add(float a, float b)
    • b. void Add(int a, int b)
    • c. int Add(int b, float b)
    • d. int Add(int a, int b)
    • 정답: d
    • 해설: int Add(int a, int b)는 정수형 매개 변수 두 개를 받아 정수형 값을 반환하는 함수입니다.

19.21. 연습문제: 곱셈 함수 만들기

다음 소스 코드를 완성하여 결과값으로 31.40이 출력되게 합니다.

코드: FunctionPractice.c

//[?] 곱셈 함수 만들기
#include <stdio.h>

// 함수 원형
double Multiply(double a, double b);

int main(void)
{
    double result = Multiply(3.14, 10.0);
    printf("결과: %.2lf\n", result);
    return 0;
}

// 함수 본문
double Multiply(double a, double b)
{
    return a * b;
}
  • 정답: double Multiply(double a, double b) { return a * b; }
  • 해설: Multiply 함수는 두 개의 double 변수를 매개변수로 받아, 이를 곱한 결과를 double 형식으로 반환합니다. 이 결과는 main 함수에서 result 변수에 저장되어 출력됩니다.

19.22. 거듭제곱 함수 만들기

거듭제곱을 계산하는 함수 pow를 구현한 코드입니다.

코드: power.c

//[?] 거듭제곱 함수 만들기
#include <stdio.h>

int pow(int a, int b)
{
    int result = 1;
    for (int i = 0; i < b; i++)
    {
        result *= a;
    }
    return result; // a의 b제곱
}

int main(void)
{
    int result = pow(2, 10);
    printf("2의 10승: %d\n", result); // 1024

    result = pow(2, 20);
    printf("2의 20승: %d\n", result); // 1048576

    return 0;
}
  • 출력 결과는 각각 2의 10승과 2의 20승인 1024와 1048576입니다.

19.23. 장 요약

함수는 C 언어 프로그래밍에서 중요한 개념으로, 코드의 반복과 중복을 줄이며 효율성을 높이는 데 기여합니다. 이번 장에서 다룬 함수의 개념과 사용법은 향후 프로그래밍 과정에서 계속해서 중요하게 다뤄질 내용입니다. 함수를 활용하여 더 깔끔하고 유지보수가 용이한 코드를 작성할 수 있습니다.

문제 풀이

정보처리기능사 실기 문제: 함수 호출을 통한 값 계산

이 문제에서는 여러 함수를 호출하여 값을 계산하고, 최종 결과를 출력하는 프로그램을 작성합니다.

#include <stdio.h>

int r1()
{
    return 4;
}

int r10()
{
    return (30 + r1());
}

int r100()
{
    return (200 + r10());
}

int main(void)
{
    printf("%d\n", r100());
    return 0;
}

해결 방법:

  1. #include <stdio.h>를 사용하여 표준 입출력 라이브러리를 포함합니다.
  2. r1, r10, 그리고 r100이라는 세 개의 함수를 정의합니다. 각 함수는 정수 값을 반환합니다.
    • r1 함수는 정수 4를 반환합니다.
    • r10 함수는 r1 함수의 반환값에 30을 더한 값을 반환합니다.
    • r100 함수는 r10 함수의 반환값에 200을 더한 값을 반환합니다.
  3. main 함수에서 r100 함수를 호출하여 반환된 값을 출력합니다. 이때, printf 함수를 사용하여 콘솔에 결과값을 출력합니다.
  4. 프로그램의 실행이 성공적으로 완료되었음을 나타내기 위해 return 0;을 사용합니다.

이 프로그램은 함수 호출과 반환값을 활용하여 연쇄적인 계산을 수행하는 방법을 이해하는 데 중점을 둡니다.

정보처리기능사 실기 문제: 팩토리얼 함수 구현

이 문제에서는 C 언어를 사용하여 주어진 숫자의 팩토리얼을 계산하는 재귀 함수 func를 구현하고, 사용자로부터 입력받은 숫자에 대해 이 함수를 사용하여 그 결과를 출력하는 프로그램을 작성하는 것이 목표입니다. 팩토리얼 함수는 자기 자신을 호출하는 재귀적 구조를 가지며, 기본적인 재귀 함수의 작동 원리를 이해하는 데 중점을 둡니다.

#include <stdio.h>

int func(int a)
{
    if (a <= 1) return 1;
    return a * func(a - 1);
}

int main(void)
{
    int a;
    scanf("%d", &a);
    printf("%d", func(a));
}

해결 방법:

  1. #include <stdio.h>를 사용하여 표준 입출력 라이브러리를 포함합니다.
  2. func 함수를 정의하여 정수 a의 팩토리얼을 계산합니다. 이 함수는 a가 1 이하일 경우 1을 반환하며, 그렇지 않은 경우 afunc(a - 1)의 곱을 반환합니다.
  3. main 함수에서 사용자로부터 정수를 입력받아 변수 a에 저장합니다.
  4. func 함수를 호출하여 입력받은 숫자의 팩토리얼을 계산하고, 그 결과를 printf 함수를 사용하여 출력합니다.

이 문제는 재귀 함수를 사용하여 팩토리얼을 계산하는 방법을 평가합니다. 재귀 함수는 함수가 자기 자신을 호출하는 구조를 가지며, 복잡한 문제를 간단하게 해결할 수 있는 중요한 프로그래밍 기법 중 하나입니다. 팩토리얼 계산은 재귀 함수의 기본적인 예제로 자주 사용됩니다.

정보처리기능사 실기 문제: 거듭제곱 계산 함수 구현

이 문제에서는 C 언어를 사용하여 주어진 밑(base)과 지수(exp)를 매개변수로 받아 거듭제곱을 계산하는 함수 mp를 구현하고, 이 함수를 사용하여 계산 결과를 출력하는 프로그램을 작성하는 것이 목표입니다. 함수 구현과 반복문 사용을 통해 기본적인 수학 연산 알고리즘을 이해하고 적용하는 능력을 평가합니다.

#include <stdio.h>

int mp(int base, int exp)
{
    int res = 1;
    for (int i = 0; i < exp; i++)
    {
        res *= base;
    }
    return res;
}

int main(void)
{
    int res = mp(2, 10);
    printf("%d", res);
}

해결 방법:

  1. #include <stdio.h>를 사용하여 표준 입출력 라이브러리를 포함합니다.
  2. mp 함수를 정의하여 주어진 밑(base)과 지수(exp)에 대한 거듭제곱 값을 계산합니다. 이 함수는 초기 결과값 res를 1로 설정하고, 지수 exp만큼 반복하면서 매 반복마다 res에 밑 base를 곱합니다.
  3. main 함수에서 mp 함수를 호출하여 2의 10제곱을 계산하고, 그 결과를 변수 res에 저장합니다.
  4. 계산된 결과 resprintf 함수를 사용하여 출력합니다.

이 문제는 반복문을 사용하여 간단한 거듭제곱 계산 알고리즘을 구현하는 방법을 이해하고, 함수를 정의하고 호출하여 특정 연산을 수행하는 기본적인 프로그래밍 개념과 기술을 평가합니다.

정보처리기사 실기 시험 C 언어 기출 문제 - 함수 호출

문제

다음 C 프로그램이 실행되었을 때의 동작을 설명하고, 출력 결과를 예측하시오.

소스 코드 파일명: exam_function_call.c

#include <stdio.h>

int r1() {
	return 4;
}

int r10() {
	return (30 + r1());
}

int r100() {
	return (200 + r10());
}

int main() {
	printf("%d\n", r100());
	return 0;
}

입력 예시

이 프로그램은 사용자로부터 입력을 받지 않습니다.

출력 예시

234

해설

이 프로그램은 여러 함수를 순차적으로 호출하여 최종적으로 계산된 값을 출력합니다.

  1. r1 함수는 4를 반환합니다.
  2. r10 함수는 r1 함수의 반환 값에 30을 더한 값을 반환합니다. 따라서 r10의 반환 값은 34입니다.
  3. r100 함수는 r10 함수의 반환 값에 200을 더한 값을 반환합니다. 따라서 r100의 반환 값은 234입니다.
  4. main 함수에서 r100 함수를 호출하고, 그 반환 값을 printf 함수를 사용하여 출력합니다. 따라서 프로그램의 최종 출력 결과는 234입니다.

이 프로그램은 함수 호출을 통해 값을 반환하고, 이러한 반환 값을 다른 함수의 연산에 사용하는 과정을 보여줍니다. 이는 함수가 어떻게 다른 함수와 상호 작용할 수 있는지를 이해하는 데 도움이 됩니다.

VisualAcademy Docs의 모든 콘텐츠, 이미지, 동영상의 저작권은 박용준에게 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다. 사이트의 콘텐츠를 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다. 단, 링크와 SNS 공유, Youtube 동영상 공유는 허용합니다. www.VisualAcademy.com
박용준 강사의 모든 동영상 강의는 데브렉에서 독점으로 제공됩니다. www.devlec.com