Phase 2 · C언어 핵심 · 활용

함수 — 코드 구조화

길고 복잡해진 코드를 하나의 덩어리로 묶어 이름을 붙여줍니다. '함수'를 만들면 코드를 레고 블록처럼 조립하여 재사용할 수 있으며, 전체 프로그램 구조를 아름답게 만들 수 있습니다.

예상 학습 시간 : 150분
난이도 : ★★★☆☆ 중급 기초
사전 지식 : 배열, 반복문
다음 단계 : 포인터
01

학습 목표

1
스스로 함수를 정의하고 호출할 수 있다.
2
매개변수(입력)와 반환값(출력)의 개념을 이해하고 활용한다.
3
반환값이 없을 때는 void 함수를 사용한다.
4
함수의 선언정의의 역할을 구분하여 작성할 수 있다.
5
배열을 통째로 함수의 매개변수로 전달할 수 있다.
6
지역변수전역변수의 차이를 이해하고 설계 원칙을 지킨다.
02

함수란?

함수(Function)는 특정 기능을 수행하도록 만들어 놓은 코드 묶음입니다.

사실 우리는 이미 수많은 함수를 써왔습니다. 화면에 텍스트를 띄워주는 printf(), 입력을 받는 scanf(), 그리고 프로그램의 시작점인 main() 모두 C언어의 함수입니다.

이제부터는 우리가 직접 나만의 기능(예: 평균 계산하기, 최댓값 찾기)을 담당하는 함수를 만들어 볼 차례입니다.

03

함수의 기본 구조

⚙️ C
// 반환형 | 함수이름 | (매개변수들...)
int add(int a, int b)
{
    // 실행할 코드
    int result = a + b;
    
    // 결과값을 함수를 부른 곳으로 돌려준다!
    return result; 
}
호출: add(10, 20)
↓ 10은 a로, 20은 b로 전달
내부: 10 + 20 실행
↓ 결과 30을 반환 (return)
최종 반환값: 30
04

매개변수와 반환값의 다양한 형태

1. 반환값이 없을 때 (void)

계산된 결과를 돌려줄 필요 없이 단순히 출력만 하고 끝내는 함수는 void(비어있다)를 반환형으로 씁니다.

⚙️ C
void greeting() {
    printf("Hello C Language!\n");
    // return이 필요 없음
}

2. 입력과 출력이 모두 있는 경우

⚙️ C
double getAverage(int sum, int count) {
    return (double)sum / count;
}
05

함수 선언(Prototype)과 정의

C언어 컴파일러는 위에서부터 코드를 읽습니다. 만약 main() 안에서 add()를 호출했는데 아직 컴파일러가 add()를 본 적이 없다면 에러를 냅니다.
이를 방지하기 위해 맨 위에 "이런 형태의 함수가 밑에 있을 것이다"라고 미리 신고하는 것을 함수 선언이라고 합니다.

⚙️ C
#include <stdio.h>

// [1] 함수 선언 (이름, 매개변수, 반환형만 적고 세미콜론)
int add(int a, int b); 

int main() {
    printf("결과: %d\n", add(10, 20)); // 안심하고 호출
    return 0;
}

// [2] 함수 정의 (실제 구현 내용)
int add(int a, int b) {
    return a + b;
}
06

배열을 함수에 전달하기

매개변수로 단일 변수(int a)뿐 아니라 배열 전체를 넘길 수 있습니다. 이때 배열의 크기를 알려주기 위해 길이를 나타내는 변수(size)도 함께 넘기는 것이 관례입니다.

📦
Practice
배열 총합 구하기 함수
⚙️ C
// 배열 매개변수는 대괄호 []를 사용합니다.
int getSum(int data[], int size) {
    int sum = 0;
    for (int i = 0; i < size; i++) {
        sum += data[i];
    }
    return sum;
}

int main() {
    int scores[5] = {10, 20, 30, 40, 50};
    
    // 배열 이름(scores)만 인자로 넘겨줍니다!
    printf("총합: %d\n", getSum(scores, 5)); 
    return 0;
}
07

지역변수(Local)와 전역변수(Global)

🏠 지역변수 (권장)

특정 중괄호 {}나 함수 내부에서 선언된 변수입니다. 해당 함수 안에서만 살아있으며 외부에서는 아예 접근할 수 없습니다. (안전성 높음)

🌍 전역변수 (주의)

모든 함수 바깥에 선언된 변수로 프로그램 전체에서 읽고 쓸 수 있습니다. 편해보이지만, 나중에 누가 값을 바꿨는지 추적하기 힘들어 치명적 버그의 원인이 됩니다.

08

가장 많이 하는 오해: 값 복사

Pass by Value (값에 의한 전달)

함수에 변수를 전달할 때, C언어는 변수 그 자체를 주는 것이 아니라 변수 안의 "값만 복사"해서 전달합니다. 즉, change(a) 함수 안에서 복사본을 지지고 볶아도 원본 a는 전혀 변하지 않습니다.

원본 변수의 값을 직접 바꾸고 싶다면? 그것이 바로 다음 단계(STEP 09)에서 배울 "포인터(Pointer)"의 역할입니다.

09

STEP 08 최종 프로젝트

🚀 Mission

함수 기반 학생 성적 관리 프로그램 리팩토링

STEP 07에서 main() 하나에 길게 늘여 썼던 코드를, 목적에 맞게 작고 아름다운 함수들로 완전히 쪼개서(리팩토링) 다시 조립해 보세요.

main()
├── inputScores(배열, 크기)
└── printResult(배열, 크기)
    ├── getSum()
    ├── getAverage()
    ├── getMax()
    └── getMin()

[추가 알고리즘 도전 과제]

  • int isPrime(int number) : 소수면 1, 아니면 0을 반환
  • char getGrade(int score) : 점수에 따라 A~F 문자를 반환
10

STEP 08 완료 체크리스트

함수 선언, 정의, 호출의 사이클을 이해하고 직접 작성할 수 있다.
입력(매개변수)과 출력(return 반환값)의 흐름을 이해한다.
의미 있는 동작 단위로 코드를 분리하여 단일 함수(단일 책임)로 만들 수 있다.
배열 자체를 매개변수 형태로 안전하게 함수에 전달할 수 있다.
지역변수의 생존 범위를 이해하고 전역변수의 남용을 지양한다.
함수 안에서 값을 바꿔도 원본은 바뀌지 않는다(값 복사)는 사실을 이해한다.
이전 : Step 07 Step 09 : 포인터