06. 함수 (Function): 코드의 마법 공장
1. 함수란 무엇인가요?
프로그래밍에서 함수(Function)는 특정한 작업을 수행하도록 독립적으로 설계된 코드의 묶음입니다. 가장 이해하기 쉬운 비유는 '마법 물약 제조기'입니다.
여러분이 사과와 허브를 제조기에 넣고 버튼을 누르면, 기계 내부에서 알아서 끓이고 섞은 뒤 '체력 회복 물약'을 뚝딱 만들어냅니다. 여기서 사과와 허브는 입력(매개변수), 기계 내부의 동작은 코드, 완성된 물약은 출력(반환값)이 됩니다.
💡 왜 함수를 써야 할까요?
1. 재사용성: 똑같은 코드를 매번 다시 적을 필요 없이, 한 번 만들어두고 필요할 때마다 이름만 불러서(호출해서) 쓸 수 있습니다.
2. 가독성: 코드를 목적에 맞게 쪼개어 놓기 때문에, 책의 목차를 보듯 프로그램의 흐름을 쉽게 파악할 수 있습니다.
2. 함수의 해부학 (구조)
C언어에서 함수를 만들 때는 다음 3가지 요소가 반드시 필요합니다.
- 반환형 (Return Type): 이 기계가 최종적으로 내뱉을 결과물의 형태 (정수형 int, 실수형 float, 없다면 void)
- 함수명 (Function Name): 이 기계를 부를 이름 (예: add, makePotion 등)
- 매개변수 (Parameters): 기계에 넣을 재료들
int makePotion(int herb, int water) {
// 내부에서 수행할 작업
int potion = herb + water;
// 결과물을 반환
return potion;
}
3. 🚀 창의적 응용 예제 1: RPG 게임 데미지 계산기
단순한 더하기가 아닌, 실제 게임에서 쓰일법한 예제를 만들어 볼까요? 용사가 몬스터를 공격할 때, 기본 공격력과 무기의 강화 수치를 조합해 최종 데미지를 계산하는 함수를 만들어 봅시다.
#include <stdio.h>
// ⚔️ 데미지 계산 함수
int calcDamage(int baseAttack, int weaponLevel) {
int finalDamage;
// 강화 수치 1당 데미지가 15씩 증가한다고 가정
finalDamage = baseAttack + (weaponLevel * 15);
return finalDamage;
}
int main() {
int myAttack = 50; // 내 기본 공격력
int swordLevel = 3; // +3 강화된 검
// 함수 호출!
int damage = calcDamage(myAttack, swordLevel);
printf("몬스터에게 %d의 데미지를 입혔습니다!\n", damage);
return 0;
}
이렇게 calcDamage라는 함수를 하나 만들어두면, 파티원이 4명이어도 이 함수 하나로 4명 모두의 데미지를 쉽게 계산할 수 있겠죠?
4. ☕ 창의적 응용 예제 2: 반환값이 없는 함수 (void)
모든 기계가 물건을 뱉어내는 것은 아닙니다. 예를 들어 '청소기'는 작동을 할 뿐이지, 새로운 물건을 반환하지는 않죠. 이렇게 행동만 하고 돌려주는 값이 없을 때는 반환형으로 void(비어있음)를 사용합니다.
#include <stdio.h>
// 커피를 만들어주는 자판기 함수 (돌려주는 데이터는 없고, 화면에 출력만 함)
void makeCoffee(int coins) {
if (coins >= 500) {
printf("☕ 위잉~ 따뜻한 아메리카노가 나왔습니다!\n");
} else {
printf("❌ 금액이 부족합니다. (500원 필요)\n");
}
}
int main() {
printf("--- 자판기 시뮬레이션 ---\n");
makeCoffee(300); // 실패하는 경우
makeCoffee(1000); // 성공하는 경우
return 0;
}
⚠️ 주의할 점: 함수의 위치
C언어는 코드를 위에서 아래로 읽어 내려갑니다. 따라서 main() 함수에서 makeCoffee()를 사용하려면, 반드시 main 함수보다 위쪽에 함수를 정의하거나, 맨 위에 '함수의 원형(Prototype)'을 선언해 주어야 합니다.
5. ✨ 창의적 응용 예제 3: 마법진 그리기 (별 찍기 함수)
프로그래밍의 꽃, '별 찍기'를 함수로 만들어 봅시다. 마법사가 주문을 외울 때마다 원하는 크기의 삼각형 마법진을 화면에 출력하는 함수입니다. 함수 내부에 반복문(for)을 넣어 복잡한 동작을 캡슐화(숨김)할 수 있습니다.
#include <stdio.h>
// 마법진(별 삼각형)을 그리는 함수
void drawMagicCircle(int size) {
printf("--- 크기 %d의 마법진 소환! ---\n", size);
for (int i = 1; i <= size; i++) {
for (int j = 1; j <= i; j++) {
printf("*");
}
printf("\n");
}
printf("--------------------------\n\n");
}
int main() {
// 원할 때마다 다른 크기로 마법진을 쉽게 그릴 수 있습니다.
drawMagicCircle(3);
drawMagicCircle(5);
return 0;
}
💡 함수의 강력함: 복잡성 숨기기
main 함수를 보세요. 이중 for문이라는 복잡한 논리가 drawMagicCircle이라는 한 줄의 함수 호출로 깔끔하게 정리되었습니다. 이것이 바로 함수가 주는 '가독성'의 마법입니다.
6. 🎮 창의적 응용 예제 4: 시각적 HP 체력바 생성기
단순히 숫자만 보여주는 것을 넘어, 현재 체력과 최대 체력을 입력받아 게임의 HP 바(Bar)를 시각적으로 그려주는 함수를 만들어 보겠습니다. 매개변수 2개를 활용해 비율을 계산합니다.
#include <stdio.h>
// 체력바를 그리는 함수 (총 10칸 기준)
void drawHealthBar(int currentHP, int maxHP) {
// 체력 비율 계산 (0.0 ~ 1.0)
float ratio = (float)currentHP / maxHP;
// 10칸 중 채워야 할 칸 수 (0 ~ 10)
int filled = ratio * 10;
printf("HP [%d/%d] [", currentHP, maxHP);
for (int i = 0; i < 10; i++) {
if (i < filled) {
printf("■"); // 남은 체력
} else {
printf("□"); // 잃은 체력
}
}
printf("]\n");
}
int main() {
printf("🔥 보스 몬스터와의 전투!\n");
drawHealthBar(1000, 1000); // 전투 시작 (100%)
drawHealthBar(650, 1000); // 데미지를 입음 (65%)
drawHealthBar(120, 1000); // 빈사 상태 (12%)
return 0;
}
7. 🔐 창의적 응용 예제 5: 비밀문 잠금 해제 (판별 함수)
함수는 계산이나 출력뿐만 아니라, '참(1)'인지 '거짓(0)'인지 판별하는 역할로도 아주 많이 쓰입니다. 사용자가 입력한 비밀번호가 맞는지 확인하여 문을 열어주는 보안 시스템 함수입니다.
#include <stdio.h>
// 비밀번호를 확인하는 함수 (맞으면 1, 틀리면 0 반환)
int checkPassword(int inputPin) {
int secretPin = 7777; // 정답 비밀번호
if (inputPin == secretPin) {
return 1; // 일치함 (참)
} else {
return 0; // 불일치 (거짓)
}
}
int main() {
int userTry = 1234;
printf("비밀번호 %d 입력 중...\n", userTry);
// 함수가 1을 반환하면 if문 실행, 0을 반환하면 else문 실행
if (checkPassword(userTry)) {
printf("🔓 비밀문이 열렸습니다. 보물방에 입장합니다!\n");
} else {
printf("🔒 삐빅! 비밀번호가 틀렸습니다. 침입자 경보!\n");
}
return 0;
}
팁: C언어에서의 참과 거짓
C언어에는 아주 오래전부터 true, false라는 단어가 기본으로 없었습니다. 대신 숫자 0은 거짓, 0이 아닌 모든 숫자(보통 1)는 참으로 인식합니다. 위 예제처럼 조건문(if) 안에 함수를 바로 넣으면 코드가 아주 우아해집니다.