본문 바로가기
C언어

C언어 기초 10. 함수 (part 1. 끝)

by algosketch 2019. 12. 14.
  • 함수
  • 전역변수와 지역변수
  • define
  • const
  • static

 이번 절에서는 함수와 #define, const에 대해 알아보겠다.

 

1. 함수

 함수는 낯설지 않은 단어이다. 누구나 중학교 수학 시간에 함수를 배웠을 것이다. 그때 배운 함수와 본질이 같다. 함수하면 어떤 생각이 드는가? y = ax+b? 코딩에서 이 표현보다는 f(x) = ax+b가 더 적절하다. 중요한 것은 함수 f(x)에 값을 대입하면 새로운 값이 나온다는 것이다. 다만, 코딩에서는 값을 대입하지 않거나 하나 이상의 값을 대입해야 할 수도 있다. 또한 새로운 값을 무조건 반환하지 않아도 된다. 함수는 다음과 같이 구성된다.

반환형 함수이름(매개변수)
{
    ... 구현부 ...
}

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

 지금까지 사용해왔던 main은 함수였다. main함수는 프로그램 진입점을 갖는 특수한 함수로 하나의 프로그램에 반드시 하나만 존재해야 한다. main함수도 매개변수를 받을 수 있는데 C언어 기초편에서는 설명하지 않으니 궁금하다면 구글에서 검색해보자.

 함수는 함수이름, 매개변수, 반환형, 구현부, 선언부로 구성된다. 함수이름은 함수를 호출할 때 사용한다. 매개변수를 이용하여 함수가 동작하는데 필요한 변수를 호출하는 쪽에서 넘겨준다. 함수가 끝나고 필요하다면 결과를 함수를 호출한 쪽으로 넘겨주는데 이 값을 반환값이라고 하고 반환값에 해당하는 자료형을 그 함수의 반환형이라고 한다.

#include <stdio.h>

int add(int a, int b) {
    int res;
    res = a + b;
    return res;
}

int main() {
    int num1, num2;
    int result;
    num1 = 5, num2 = 10;
    result = add(num1, num2);
    printf("%d\n", result);

    return 0;
}
output
15

 

 함수의 역할은 매개변수 2개를 받아서 두 값의 합을 반환한다. main함수에서는 값 두 개를 넘겨주면 두 값의 합이 나올 것을 기대한다. 함수 중에는 반환형이나 매개변수가 필요 없는 경우도 있는데 그 경우에는 void를 적어준다. 매개변수 부분에는 void 생략이 가능하다.

#include <stdio.h>

void printHello() {
    printf("Hello\n");
}

int main(void) {
    printHello();

    return 0;
}
output
Hello

 

 컴파일러는 코드를 순서대로 읽게 되는데 함수를 main함수보다 아래에 선언하게 되면 main함수에서 함수 호출을 만났을 때 에러를 발생시킨다. 정의되지 않은 함수로 인식하기 때문이다. 따라서 main함수보다 함수를 위에다가 선언한 것이다. main함수 위의 코드가 길어지는 게 싫다면 다음과 같이 함수의 선언부와 구현부를 분리하여 작성할 수도 있다.

#include <stdio.h>

void printHello(); // 함수의 선언부

int main(void) {
    printHello();

    return 0;
}

void printHello() { // 함수의 구현부
    printf("Hello\n");
}

 함수의 반환형, 이름, 매개변수에 대한 정보 작성 수 세미콜론(;)을 찍어준다.

 

2. 전역변수와 지역변수

 중괄호{} 안에서 선언된 변수는 그 괄호가 끝나는 지점까지만 사용할 수 있다. 위에서 작성된 코드(add 함수가 있는 코드)로 예를 들면 main함수에서는 a, b 변수를 사용할 수 없고 add함수에서는 num1, num2 변수를 사용할 수 없다. 변수 이름 재사용도 가능하다. 함수를 표현하는 중괄호 범위 안에서 선언된 변수를 지역변수라고 한다.

 반대로, 전역변수는 함수 밖에서 선언된 변수로 모든 함수에서 접근이 가능하다.

#include <stdio.h>

int every = 10;

void print() {
    printf("%d", every);
}

int main() {
    printf("%d", every);

    return 0;
}
output
1010

 

 함수가 아니라 중괄호로 지역을 나누어 설명한 이유가 있다. 조건문이나 반복문에서 사용하는 중괄호도 하나의 지역으로 인식할 수 있다. 다음과 같은 코드도 가능하다.

int a = 5;
if(1) {
    int a = 8;
    printf("%d", a); // 더 안쪽 괄호에서 선언된 변수가 우선시 되며, 바깥 변수에 영향을 미치지 않는다.
}
printf("%d", a);
output
85

 하지만 이런 코드는 가독성을 해치기 때문에 지양해야 한다.

 전역변수는 모든 함수에서 접근이 가능하기에 만능 변수처럼 보인다. 실제로 100줄 이하의 코드, 길어질 가능성이 없는 코드에서는 선호하는 변수이기도 하다. 하지만 코드가 길어지면 전역변수 하나를 수정했을 때 모든 함수에 영향을 끼칠 가능성이 있기 때문에 지양해야할 변수이다.

 

3. define

#define LEVEL_MAX 20

 위와 같이 사용한다. LEVEL_MAX = 20 이라고 생각하면 된다. 그리고 이것을 매크로라고 한다. 매크로를 이용하여 간단한 함수도 정의가 가능하다.

#define F(X) 3*(X)+2

 f(x) = 3x+2 를 매크로로 정의한 것이다. 매크로 함수를 사용할 때 변수에 해당하는 부분은 괄호로 묶어주는 것이 예상치 못한 오류를 예방하는 데 좋다.

 

4. const

 const는 constant에서 따온 단어인 것 같다. const는 안전한 프로그래밍을 위해 사용한다. 변수 선언 앞에 const를 붙이면 그 변수 값을 변경하려고 할 때 컴파일 에러를 발생시킨다. 변수의 값을 변경할 필요가 없는 변수(상수)를 선언할 때 사용하여 프로그래머의 실수를 방지한다. 그리고 이렇게 선언된 변수를 상수라고 부르고 선언과 동시에 초기화해야 한다.

const int maximum = 20; // 재초기화 불가

 

5. static

 프로그램에는 컴파일과 런타임 시점이 존재한다. 컴파일 시점에 발생하는 에러는 컴파일 에러, 런타임(프로그램 실행) 시점에 발생하는 에러는 런타임 에러이다. 그리고 컴파일 시점에 초기화되는 변수는 정적 변수, 런타임 시점에 초기화되는 변수는 동적 변수라고 한다. 우리가 지금까지 사용해온 변수는 동적 변수이다. 프로그램 코드를 한 줄이 읽어가며 초기화 코드를 읽었을 때 비로소 변수가 초기화 된다. 지금은 컴파일 시점에 초기화되는 변수를 알아보려고 한다.

 정적 변수는 자료형 앞에 static을 붙여 사용한다. 코드상으로 저 아래에 있어도 실제로 초기화되는 건 컴파일 시점이기 때문에 프로그램이 실행되고 있다면 프로그램은 시작하자마자 변수의 존재를 인지한다. 그리고 그 변수는 프로그램 종료 시점까지 존재한다.

#include <stdio.h>

void function() {
    static int count = 0;
    ++count;
    printf("%d번째 호출\n", count);
}

int main() {
	for(int i = 0; i < 5; ++i) {
        function();
    }

    return 0;
}
output

1번째 호출

2번째 호출

3번째 호출

4번째 호출

5번째 호출

 

 정적 변수는 전연 변수를 사용해야 하는 특정 상황에 대한 대안으로 사용할 수 있다.

'C언어' 카테고리의 다른 글

C언어 기초 part 2-2. 다차원 배열  (1) 2020.01.31
C언어 기초 part 2-1. 배열  (0) 2020.01.21
C언어 기초 9. 반복문  (0) 2019.12.07
C언어 기초 8. 조건문  (0) 2019.09.12
C언어 기초 7. C언어 연산  (0) 2019.09.07