Skip to main content

Command Palette

Search for a command to run...

Function Prototype and Library Function (2/2)

함수 원형과 라이브러리 함수 (C언어)

Updated
15 min read
Function Prototype and Library Function (2/2)

Contents


1️⃣ 함수 원형과 라이브러리 함수


1️⃣ 함수 원형과 라이브러리 함수

함수 원형(Function Prototype)의 필요성

💡요약: 함수 원형(Function Prototype)은 함수가 사용되기 전에 컴파일러에게 함수의 정보를 알려주는 선언이다. 함수 원형이 없으면 컴파일러가 함수 호출을 인식하지 못해 오류(Error) 가 발생하게 된다. 이 문제는 함수 원형을 main 함수 위에 추가(Add Prototype above main)하여 해결할 수 있다.

아래의 코드를 실행하면 오류가 발생하게 된다.

  1. 오류 원인(Error Cause): main 함수에서 c_to_f 함수를 호출하고 있지만, c_to_f 함수의 원형(Prototype)이 main 함수 앞에 선언되지 않아 컴파일러(Compiler)가 함수의 존재를 알지 못한다.

  2. 함수 원형(Function Prototype): 함수가 사용되기 전에 컴파일러에게 해당 함수의 이름, 반환형, 매개변수 타입을 알려주는 선언이다. 함수 원형이 없다면, 컴파일러는 함수를 처음 호출할 때 그 함수가 존재하는지 알 수 없어서 오류를 발생시킨다.

  3. 해결 방법(Solution): main 함수 앞에 c_to_f 함수의 원형(Prototype)을 추가하면 컴파일 오류가 사라지게 된다. double c_to_f(double c_temp); 라는 선언을 main 함수 위에 넣으면 된다.


함수 원형(Function Prototype)의 역할과 작성 방법

💡요약: 컴파일러가 함수 호출을 이해할 수 있도록 함수의 기본 정보를 미리 알려주는 선언을 함수 원형이라고 한다. 함수 정의 이전에 작성하며, 함수 원형에서는 매개변수의 이름을 생략할 수 있다.

  • 함수 원형의 구성 요소(Components of Function Prototype)

    • 함수의 이름(Name), 매개변수(Parameters), 그리고 반환형(Return Type)을 함수가 정의되기 전에 선언한다.

    • 함수 원형은 실제 함수 정의와 거의 같지만, 매개변수의 이름은 생략해도 되고 자료형만(Only the Data Type) 작성할 수 있다.

  • 함수 헤더와의 차이점(Difference from Function Header):

    • 함수 원형은 함수의 헤더와 유사하지만, 함수의 실제 내용을 담지 않고 단순히 세미콜론(;)을 추가하는 것으로 끝난다.

    • 함수의 헤더(Header)는 실제 함수 정의에 포함되며, 함수 원형(Prototype)은 함수 호출 전에 미리 선언하기 위한 것이다.

💡예시 코드:

  • 함수 원형: double c_to_f(double);

  • 함수 정의: double c_to_f(double c_temp) { /* 함수 내용 */ }

  • 여기서 함수 정의에서는 매개변수 이름을 명시하지만, 함수 원형에서는 자료형만 적어도 괜찮다.


함수 원형을 사용하지 않는 경우(Examples Without Function Prototypes) 발생할 수 있는 문제와 예외적인 상황

💡요약: 함수 원형(Function Prototype)은 함수가 정의되기 전에 선언하는 것이 일반적인 방법(Standard Practice)이다. 함수 원형이 없으면 순환 호출이나 호출 순서에 따라 컴파일 오류(Compile Errors)가 발생할 수 있다. 특히 순환 호출(Mutual Recursion)과 같은 상황에서는 함수 원형이 필수적이다.

  • 함수 정의가 먼저 오는 경우(When Function Definition Comes First):

    • 첫 번째 예제에서는 compute_sum 함수가 main 함수(main function)보다 먼저 정의되어 있어서 함수 원형(Function Prototype)을 사용하지 않아도 문제가 발생하지 않습니다. 그러나 이 방법은 일반적이지 않는다.

    • 보통 함수 원형을 먼저 선언해 두는 것이 가독성(Readability)과 유지보수(Maintainability)에 좋다.

  • 순환 호출(Mutual Recursion) 상황:

    • 두 번째 예제에서는 sub1sub2 함수가 서로 호출하는 순환 호출(Mutual Recursion) 구조이다. 이 경우 함수가 서로를 참조해야 하므로 함수 원형 없이는 컴파일 오류(Compile Error)가 발생할 수 있다.

    • 이러한 구조에서는 반드시 함수 원형(Function Prototype)을 사용하여 컴파일러가 두 함수의 존재를 인식하게 해야 한다.

  • 오류 메시지(Error Messages):

    • 두 번째 예제에서는 sub2 함수가 정의되기 전에 sub1에서 호출되므로 정의되지 않았다는 오류(Undefined Function Error)가 발생하였다. 이 문제는 함수 원형을 사용하여 해결할 수 있다.

중간 점검(Midpoint Check)

💡요약: 함수 정의(Function Definition)와 함수 원형(Function Prototype)의 주요 차이점과 각각의 역할을 이해하는 것이 중요하다. 함수 원형을 통해 반환형과 매개변수 정보를 미리 알 수 있으며, 함수가 값을 반환하지 않는 경우 void를 사용하여 정의할 수 있다.

1. 함수 정의의 첫 번째 줄에 포함되는 정보는 무엇인가?

  • 함수 정의의 첫 줄에는 함수 이름(Function Name), 반환형(Return Type), 매개변수 타입(Parameter Types) 등이 포함된다.

  • 이러한 요소들은 함수 원형(Function Prototype)과 동일하게 나타나며, 함수가 어떤 값을 반환하고 어떤 인자를 받는지 컴파일러에게 알려준다.

2. 함수가 반환할 수 있는 값의 개수는?

  • C 언어에서 함수는 하나의 값만 반환(Only One Return Value)할 수 있다. 여러 개의 값을 반환하려면 포인터나 구조체를 사용해야 한다.

3. 함수가 값을 반환하지 않는다면 반환형은 어떻게 정의되어야 하는가?

  • 반환할 값이 없는 함수는 void를 반환형으로 정의한다.

  • 예를 들어, void print_message(void);와 같이 void 키워드를 사용하여 값을 반환하지 않음을 명시할 수 있다.

4. 함수 정의와 함수 원형의 차이점은 무엇인가?

  • 함수 정의(Function Definition)에는 함수의 실제 코드 구현이 포함된다.

  • 반면에, 함수 원형(Function Prototype)은 함수가 어떤 반환형과 매개변수를 가지는지 미리 알려주는 선언이며, 세미콜론(;)으로 끝난다.

  • 함수 정의는 프로그램이 실행될 때 실제로 어떤 작업을 수행할지 결정하지만, 함수 원형은 컴파일러에게 함수의 존재를 미리 알려주는 역할을 한다..

5. 다음과 같은 함수 원형을 보고 우리가 알 수 있는 정보는 무엇인가?

double pow(double, double);
  • 반환형(Return Type): pow 함수는 double 형 값을 반환한다.

  • 함수 이름(Function Name): 함수의 이름은 pow이다.

  • 매개변수 타입(Parameter Types): pow 함수는 두 개의 double 타입 인자를 받는다.

  • 이 함수 원형을 통해 우리는 pow 함수가 두 개의 double 값을 인자로 받아 하나의 double 값을 반환하는 기능임을 알 수 있다.

pow power의 줄임말로, C 언어에서 사용되는 수학 함수이다. 이 함수는 거듭제곱(Exponentiation)을 계산하는 역할을 한다. 즉, 주어진 밑(base)지수(exponent)를 받아 밑을 지수만큼 거듭제곱한 값을 반환한다.


라이브러리 함수(Library Function)

💡요약: 라이브러리 함수(Library Function)는 컴파일러가 제공하는 기본적인 함수들로, 입출력, 수학 연산, 문자열 처리, 시간 처리, 오류 처리, 데이터 검색과 정렬 등의 다양한 기능을 포함한다. 이를 통해 개발자는 복잡한 기능을 쉽게 구현할 수 있게 된다.

Library Functions In C | Header Files, Uses & More (+ Examples)

☑️표준 입력과 출력(Standard Input/Output):

  • 입력(Input)과 출력(Output)을 처리하는 함수들다. 예를 들어, printfscanf 함수는 화면에 출력하고 입력을 받는 데 사용된다.

☑️수학 연산(Mathematical Operations):

  • 다양한 수학 계산을 위한 함수들이다. 예를 들어, 제곱을 구하는 pow 함수, 제곱근을 구하는 sqrt 함수 등이 있다. 이런 함수들은 <math.h> 헤더 파일에 포함되어 있다.

☑️ 문자열 처리(String Manipulation):

  • 문자열을 다루기 위한 함수들이다. 예를 들어, strcpy, strlen, strcat 등은 문자열 복사, 길이 확인, 문자열 연결 등의 작업을 수행한다.

☑️시간 처리(Time Handling):

  • 시간과 날짜를 다루는 함수들이다. 예를 들어, time 함수는 현재 시간을 가져오는 데 사용된다. 이런 함수들은 <time.h> 헤더 파일에 포함되어 있다.

☑️오류 처리(Error Handling):

  • 프로그램 실행 중 발생할 수 있는 오류를 처리하는 함수들이다. 예를 들어, perror 함수는 오류 메시지를 출력하는 데 사용된다.

☑️데이터 검색과 정렬(Data Searching and Sorting):

  • 배열 등의 데이터를 검색하거나 정렬하는 함수들이다. 예를 들어, qsort는 배열을 정렬하고, bsearch는 배열에서 값을 찾는 데 사용된다.

난수 함수(Random Number Function)

💡요약: 난수는 규칙성이 없는 임의의 수(Random Number)로, 암호학, 시뮬레이션, 게임과 같은 다양한 분야에서 필수적으로 사용된다. 이 중에서 rand() 함수(rand function)는 C 언어에서 임의의 수(Random Number)를 생성하는 기본 함수로, 0에서 RAND_MAX 사이의 값을 반환한다.

  • 난수(Random Number):

    • 난수는 예측할 수 없는 임의의 수로, 규칙성이 없다. 암호학(Cryptography)이나 시뮬레이션(Simulation), 게임(Games)에서 자주 사용된다.
  • rand() 함수:

    • rand() 함수는 C 언어에서 난수를 생성하는 함수이다.

    • rand() 함수는 0부터 RAND_MAX까지의 정수 난수를 반환한다. RAND_MAXrand() 함수가 반환할 수 있는 최대 값으로, 컴파일러마다 다를 수 있다.

💡예제: 기본 예제: 0부터 RAND_MAX 사이의 난수 생성

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("난수 생성: %d\n", rand());  // 0에서 RAND_MAX 사이의 난수 생성
    return 0;
}

  • 이 예제는 rand() 함수를 사용하여 0에서 RAND_MAX 사이의 임의의 정수 난수를 출력한다.

예제: 로또번호 생성하기 (Generate lottery number)

💡첫번째 시도: 로또 번호 생성(Generating Lotto Numbers) 프로그램을 작성하려면 1에서 45 사이의 난수를 생성해야 한다. 기본 예제 코드에서는 rand() 함수를 사용해 난수를 생성하지만, 로또 범위에 맞게 수정이 필요하다.

  • 로또 번호 생성 규칙:

    • 로또 번호는 1부터 45 사이의 숫자(Numbers Between 1 and 45)로 구성된다.

    • 이 숫자들은 6개가 필요하며, 필요에 따라 보너스 번호를 추가할 수 있다.

  • 기본 난수 생성 코드:

    • 예제 코드에서는 rand() 함수를 사용하여 6개의 난수를 생성한다.

    • rand() 함수는 0에서 32767 사이의 난수(Random Number Between 0 and 32767)를 생성한다. 하지만 로또 번호 범위는 1부터 45이므로, 이 코드는 수정이 필요하다

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int i;
    for (i = 0; i < 6; i++) {
        printf("%d ", rand());  // rand() 함수로 난수 생성
    }
    return 0;
}

  • 이 코드는 rand() 함수를 사용해 6개의 난수를 출력하였다. 하지만 1부터 45 사이의 숫자가 아니라 0에서 32767 사이의 숫자를 생성하였다.

  • 로또 번호 생성에 적합한 값을 얻기 위해서는 rand() % 45 + 1과 같이 범위를 제한해야 한다.


💡두번째 시도: 난수를 1부터 45로 제한하는 방법이다. rand() 함수는 기본적으로 0에서 RAND_MAX까지의 값을 반환하므로, 특정 범위로 제한하려면 추가적인 계산이 필요하다. |

  • 1부터 45 사이 난수 생성:

    • printf("%d ", 1 + (rand() % 45)); 코드를 사용하여 1부터 45 사이의 난수를 생성할 수 있다.

    • rand() % 45는 0에서 44까지의 값을 생성하고, 여기에 1을 더하여 1부터 45 사이의 값을 얻는다.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int i;
    for (i = 0; i < 6; i++) {
        printf("%d ", 1 + (rand() %45));  // rand() 함수로 난수 생성
    }
    return 0;
}

  • 동일한 난수 생성 문제:

    • 코드에서 매번 실행할 때마다 동일한 난수가 생성된다. 이는 난수를 생성할 때 시드(seed)가 고정되어 있기 때문이다.

    • 동일한 난수 문제 해결을 위해 srand() 함수를 사용하여 시드를 현재 시간으로 설정해야 한다.


💡세번째 시도: 난수를 매번 다르게 생성하기 위해 시드(seed)를 설정할 것이다. 시드는 난수 생성의 시작값을 의미하며, 시드를 매번 다르게 설정해야 프로그램을 실행할 때마다 다른 난수가 생성되게 된다.

시드 설정:

  • 현재 시간을 시드로 설정(Setting Seed with Current Time)하는 것이 가장 일반적인 방법이다. time(NULL) 함수는 현재 시간을 반환하며, 이를 시드로 사용하면 프로그램을 실행할 때마다 다른 난수가 생성된다.

  • 코드에서는 srand((unsigned)time(NULL));를 사용하여 시드를 설정하고 있다.

  • #include <time.h> 를 추가해야한다.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX 45

int main(void) {
    int i;
    srand((unsigned)time(NULL));   // 시드를 현재 시간으로 설정하여 난수를 다르게 생성
    for (i = 0; i < 6; i++) {
        printf("%d ", 1 + (rand() %MAX));   // 1부터 45 사이의 난수 출력
    }
    return 0;
}
  • srand((unsigned)time(NULL));을 통해 현재 시간을 시드로 설정하면 매번 다른 난수를 생성하였다.

  • 1 + rand() % MAX1부터 45 사이의 난수를 생성한다.

  • 현재 시간을 시드로 사용하는 이유:

    • 현재 시간은 매초마다 변하므로, 이를 시드로 사용하면 프로그램을 재실행할 때마다 다른 시드값이 적용되어 다른 난수 시퀀스(Different Random Sequence)를 생성한다.


예제2 - 동전 던지기 게임(Flip the coin)

  • 함수 정의:

    • coin_toss 함수가 동전 던지기 결과를 반환한다. 이 함수는 1 또는 0을 반환하여 1이면 앞면, 0이면 뒷면을 나타내는 방식으로 동작한. (실제 함수 구현이 이미지는 보이지 않지만, 보통 rand() % 2로 1 또는 0을 생성합니다.)
  • 난수 생성 초기화:

    • srand((unsigned)time(NULL));를 사용해 시드(Seed)를 현재 시간으로 설정합니다. 이렇게 하면 매번 프로그램을 실행할 때마다 다른 난수 시퀀스를 생성하므로, 동전 던지기 결과도 매번 다르게 나온다.
  • 반복문을 사용한 동전 던지기:

    • for 반복문을 사용하여 100번 동전을 던집니다. 각 반복에서 coin_toss()를 호출해 결과가 1이면 heads(앞면)를 증가시키고, 그렇지 않으면 tails(뒷면)를 증가시킨다.
  • 결과 출력:

    • 100번의 던지기가 끝나면 앞면과 뒷면이 나온 횟수를 화면에 출력한다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int coin_toss(void) {
    return rand() % 2;  // 1이면 앞면, 0이면 뒷면
}

int main(void) {
    int toss;
    int heads = 0;
    int tails = 0;
    srand((unsigned)time(NULL));  // 시드 설정

    for (toss = 0; toss < 100; toss++) {
        if (coin_toss() == 1)
            heads++;
        else
            tails++;
    }

    printf("동전의 앞면: %d\n", heads);
    printf("동전의 뒷면: %d\n", tails);

    return 0;
}

  • srand((unsigned)time(NULL));를 사용해 시드를 현재 시간으로 설정하여 매번 다른 난수를 생성하였다.

  • coin_toss() 함수는 동전 던지기를 시뮬레이션하여 1(앞면) 또는 0(뒷면)을 반환한다.

  • 100번 던진 결과로 앞면과 뒷면이 나온 횟수를 화면에 출력한다. 이 숫자는 매번 바뀐다.


예제3- 자동차 경주 게임 (Car Speed Game)

  • 난수 초기화:

    • 경주를 시작하기 전에 난수를 설정한다. srand((unsigned)time(NULL));와 같은 방식으로 시드를 설정하면, 프로그램이 매번 실행될 때마다 다른 결과를 얻을 수 있다.
  • 자동차 이동 거리 결정:

    • for 반복문을 사용하여 각 자동차의 이동을 반복한다.

    • 각 반복에서 rand() 함수를 통해 난수를 생성하여 각 자동차의 이동 거리에 누적한다.

  • 자동차 출력 함수 disp_car:

    • disp_car 함수는 자동차 번호와 이동한 거리에 따라 화면에 자동차의 위치를 표시한다.

    • distance/10만큼 *을 출력하여 자동차가 이동한 거리를 시각적으로 보여준다.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void disp_car(int car_number, int distance) {
    int i;
    printf("CAR #%d: ", car_number);
    for (i = 0; i < distance / 10; i++) {
        printf("*");
    }
    printf("\n");
}

int main(void) {
    int car1_distance = 0;
    int car2_distance = 0;
    int i;

    srand((unsigned)time(NULL));  // 난수 초기화

    for (i = 0; i < 10; i++) {  // 10번 반복
        car1_distance += rand() % 100;  // 자동차 1의 주행 거리 증가
        car2_distance += rand() % 100;  // 자동차 2의 주행 거리 증가

        disp_car(1, car1_distance);  // 자동차 1 출력
        disp_car(2, car2_distance);  // 자동차 2 출력
    }

    return 0;
}
  • 난수를 사용해 이동 거리를 결정하는 자동차 경주 게임을 구현하였다.
  • disp_car 함수는 자동차 번호와 이동 거리를 바탕으로 *를 출력해 자동차의 진행 상황을 시각화한다.

  • rand() 함수를 사용해 매번 다른 이동 거리를 설정하고, srand((unsigned)time(NULL));를 통해 매번 실행할 때마다 결과가 달라지도록 설정하였다.


예제3- 자동차 경주 게임 차3대 (3 Cars Speed Game)


표준 라이브러리 - 수학 함수 (Standard Library - Mathematical Functions)

  • 수학 라이브러리 함수(Mathematical Library Functions):

    • 복잡한 계산(Complex Calculations)을 할 때 수학 함수를 사용하면 편리하다. 이러한 함수들은 미리 정의되어 있어, 필요한 수식을 쉽게 처리할 수 있다.
  • math.h 헤더 파일:

    • 수학 함수들은 math.h 헤더 파일에 포함되어 있다. 이 파일을 포함(include)하면 다양한 수학 함수를 사용할 수 있게 된다.

    • 예를 들어, 제곱근을 계산하는 sqrt() 함수, 지수를 계산하는 pow() 함수 등이 있다.

  • double 형 반환:

    • 대부분의 수학 함수는 double 형(Double Type) 매개변수와 반환값을 가진다. 이는 수학 함수들이 일반적으로 소수점 이하의 값을 다루기 때문이다.


floor() function & ceil() function

💡요약: 이 두 함수는 소수를 처리할 때 유용하며, 소수점 이하의 값을 버리거나 올림하는 기능을 제공한다.

  • floor() 함수:

    • floor() 함수는 주어진 값의 소수점 이하를 버리고 가장 가까운 작은 정수(Nearest Lower Integer)로 내림한다.

    • 예를 들어, value가 1.6일 때, floor(1.6)은 1.0을 반환한다.

  • ceil() 함수:

    • ceil() 함수는 주어진 값의 소수점 이하를 올리고 가장 가까운 큰 정수(Nearest Higher Integer)로 올림한다.

    • 예를 들어, value가 1.6일 때, ceil(1.6)은 2.0을 반환한다.

#include <stdio.h>
#include <math.h>  // floor()와 ceil() 함수를 사용하기 위한 헤더 파일

int main() {
    double result, value = 1.6;

    result = floor(value);   // result는 1.0이다.
    printf("%lf\n", result);

    result = ceil(value);    // result는 2.0이다.
    printf("%lf\n", result);

    return 0;
}

  • 헤더 파일 추가:

    • #include <math.h>: floor()ceil() 함수를 사용하기 위해 math.h 헤더 파일을 추가하였다.
  • main() 함수 안에 코드 넣기:

    • C 언어에서는 모든 실행 코드는 반드시 main() 함수와 같은 함수 안에 있어야 한다. 그래서 result = floor(value);result = ceil(value); 코드를 main() 함수 안에 넣었다.

fabs() function

  • fabs() 함수는 주어진 실수의 절대값(Absolute Value)을 반환한다. 절대값은 숫자의 부호를 제거한 값이다.

  • 예를 들어, 12.0-12.0의 절대값은 모두 12.0이다.

예제:

#include <stdio.h>
#include <math.h>  

int main(void) {
printf("12.0의 절대값은 %f\n", fabs(12.0));
printf("-12.0의 절대값은 %f\n", fabs(-12.0));

return 0;
}
    • 이 코드에서는 fabs(12.0)fabs(-12.0)의 결과를 출력한다.

      • fabs(12.0)12.0을 반환하고, fabs(-12.0)12.0을 반환한다.

      • fabs() 함수는 math.h 헤더 파일에 포함되어 있다.


pow() & sqrt()

두 함수는 각각 거듭제곱과 제곱근을 계산할 때 사용된다.

  • pow() 함수:

    • pow() 함수는 주어진 숫자의 거듭제곱(Exponentiation)을 계산한다.

    • 예를 들어, pow(10.0, 3.0)은 10의 3제곱을 계산하여 1000을 반환한다.

    • 이 함수는 첫 번째 인수로 (base), 두 번째 인수로 지수(exponent)를 받는다.

  • sqrt() 함수:

    • sqrt() 함수는 주어진 숫자의 제곱근(Square Root)을 계산한다.

    • 예를 들어, sqrt(16)은 16의 제곱근을 계산하여 4를 반환한다.

#include <stdio.h>
#include <math.h>  

int main(void) {
printf("10의 3승은 %.0f\n", pow(10.0, 3.0));
printf("16의 제곱근은 %.0f\n", sqrt(16));

return 0;
}


삼각 함수(Trigonometric Functions)- cos(), sin(), tan()

위의 함수들은 각도를 입력으로 받아 코사인, 사인, 탄젠트 값을 계산한다.

  • math.h 헤더 파일 포함:

    • math.h 헤더 파일에는 다양한 수학 함수들이 포함되어 있으며, 삼각 함수인 sin(), cos(), tan()도 이 파일에 정의되어 있다.

    • math.h를 포함하면 다양한 수학 함수들을 사용할 수 있게 된다.

  • sin(), cos(), tan() 함수:

    • sin(double x): 주어진 각도의 사인 값(Sine Value)을 계산한다.

    • cos(double x): 주어진 각도의 코사인 값(Cosine Value)을 계산한다.

    • tan(double x): 주어진 각도의 탄젠트 값(Tangent Value)을 계산한다.

    • 이 함수들은 각도를 라디안 값으로 받아서 계산을 수행한다.

#include <math.h>
#include <stdio.h>

int main(void) {
    double pi = 3.1415926535;
    double x, y;

    x = pi / 2;          // 90도에 해당하는 라디안 값
    y = sin(x);          // sin(90도) 계산
    printf("sin( %f ) = %f\n", x, y);

    y = cos(x);          // cos(90도) 계산
    printf("cos( %f ) = %f\n", x, y);

    return 0;
}

  • 여기서 xpi / 2로 설정하여 90도에 해당하는 라디안 값으로 설정한다.

  • sin(x)는 1을 반환하고, cos(x)는 0을 반환한다.

  • sin(1.570796) = 1.000000cos(1.570796) = 0.000000이 출력되다.


exit(), system(), time() Function

  • exit() 함수:

    • exit() 함수는 프로그램을 즉시 종료할 때 사용한다. 이 함수가 호출되면, 이후의 코드는 실행되지 않고 프로그램이 종료되게 된다.
  • system() 함수:

    • system() 함수는 운영 체제 명령을 실행할 수 있게 한다.

    • 예를 들어, system("dir");는 현재 디렉토리의 파일 목록을 출력하고, system("cls");는 콘솔 화면을 지운다.

    • 이 함수를 통해 DOS 명령어(DIR, COPY, DEL, MKDIR 등)를 직접 실행할 수 있다.

  • time(NULL) 함수:

    • time(NULL)은 현재 시간을 반환한다.

    • 반환된 값은 1970년 1월 1일부터 현재까지의 초 단위 시간이니다.

    • 이 값은 주로 난수의 시드값을 설정하거나 시간 관련 계산에 사용된다.

#include <stdlib.h>
#include <stdio.h>

int main(void) {
    system("dir");  // 현재 디렉토리 목록을 출력
    printf("아무 키나 치세요\n");
    getchar();      // 키 입력 대기
    system("cls");  // 화면을 지움

    return 0;
}

  • system("dir"); 명령을 통해 현재 디렉토리의 파일 목록이 출력된다.

  • printf("아무 키나 치세요\n");로 메시지를 출력하고 getchar()로 키 입력을 기다린다.

  • 사용자가 키를 입력하면 system("cls");로 화면이 지워진다.


함수를 사용하는 이유

💡요약: 함수는 코드 중복을 줄이고(Reduce Code Duplication), 다른 프로그램에서도 재사용 가능(Reusable in Other Programs)하며, 복잡한 문제를 단순하게 나누어 해결하는 데 도움을 준다.

  • 소스 코드의 중복성을 없애준다:

    • 함수를 사용하면 동일한 작업을 여러 번 반복해서 작성할 필요 없이, 함수를 호출하여 간단히 처리할 수 있다.

    • 이로 인해 코드가 더 간결해지고 유지보수가 용이해진다.

  • 재사용 가능:

    • 한 번 작성된 함수는 다른 프로그램에서도 재사용할 수 있다. 이를 통해 코드 작성 시간을 절약하고 일관성을 유지할 수 있게된다.

    • 예를 들어, 수학 계산을 위한 함수나 데이터 처리를 위한 함수는 여러 프로그램에서 재사용할 수 있다.

  • 복잡한 문제를 단순한 부분으로 분해:

    • 함수를 사용하면 복잡한 문제를 여러 작은 부분으로 나눌 수 있다. 각각의 함수가 작은 단위의 작업을 수행하도록 설계하면, 전체 프로그램 구조를 이해하고 관리하기가 쉬워진다.

    • 예를 들어, 큰 계산을 여러 단계로 나누고 각 단계를 함수로 작성할 수 있다.


복잡한 프로그램을 함수로 분리한다.

  • 복잡한 코드의 문제:

    • 처음의 main 함수는 하나의 긴 코드로 작성되어 있다. 리스트를 읽어오고, 정렬하고, 출력하는 각 기능이 모두 main 함수 안에 있다.

    • 코드가 복잡하게 얽혀 있어서, 프로그램이 어떤 작업을 수행하는지 파악하기 어렵고 유지보수가 어렵게 된다.

  • 함수로 분리하여 단순화:

    • main 함수에서 각 작업을 별도의 함수로 분리하여 단순하게 만들 수 있다.

    • read_list(): 리스트를 읽어오는 함수

    • sort_list(): 리스트를 정렬하는 함수

    • print_list(): 정렬된 리스트를 출력하는 함수

  • 함수로 분리한 코드의 장점:

    • 각 함수가 한 가지 작업만 담당하기 때문에 코드의 가독성(Readability)이 높아진다.

    • 특정 기능을 수정하거나 개선할 때 그 함수만 수정하면 되므로 유지보수(Maintainability)가 용이해진다.

    • main 함수가 더 간결해져 프로그램의 흐름을 쉽게 이해할 수 있다.


모듈화(Modularization)

💡요약: 모듈화는 큰 프로그램을 여러 개의 모듈(Modules)로 나누어 구성하는 방법으로, 각 모듈이 독립적으로 동작하고 상호 작용을 최소화하도록 설계하는 것이 목표로 한다.

  • 좋은 모듈화:

    • 좋은 모듈화에서는 모듈 간의 상호 작용이 최소화(Minimal Interaction Between Modules)된다.

    • 예를 들어, 모듈 1모듈 2와만 상호 작용하고, 모듈 3과는 간접적으로 연결된다. 이렇게 하면 모듈 간의 연결이 단순해져서 프로그램을 이해하고 유지보수하기가 쉬워진다.

  • 나쁜 모듈화:

    • 나쁜 모듈화에서는 모듈 간의 상호 작용이 복잡(Complex Interaction Between Modules)해진다.

    • 예를 들어, 모듈 1모듈 2가 서로 여러 번 연결되어 있고, 모듈 3과도 여러 관계가 얽혀 있다. 이렇게 되면 모듈 간의 의존성이 높아져서 코드 수정 시 에러가 발생할 가능성이 높아지고 유지보수가 어려워지게 된다.

  • 좋은 모듈화의 장점:

    • 모듈 간의 연결이 단순할수록 각 모듈이 독립적으로 기능을 수행하기 쉬워진다.

    • 코드 수정이나 기능 확장이 필요한 경우, 해당 모듈만 수정하면 되므로 유지보수가 용이(Ease of Maintenance)하다.