서론: 우주선을 통째로 만드는 사람은 없다
아폴로 우주선은 부품 수만 300만 개가 넘습니다. 만약 엔지니어들이 이 거대한 기계를 처음부터 끝까지 한 번에 조립하려고 했다면, 인류는 아직 달에 가지 못했을 것입니다. 우리는 엔진, 통신 장비, 생명 유지 장치 등 '기능(Function)'별로 부품을 따로 만들고, 마지막에 이것들을 결합하는 방식을 씁니다.
프로그래밍도 마찬가지입니다. 많은 입문자가 main() 함수 하나에 수백, 수천 줄의 코드를 길게 늘어뜨려 작성합니다. 이것은 우주선을 통째로 주물러서 만들려는 것과 같습니다.
오늘 8편에서는 함수(Function)가 단순한 '코드 저장소'가 아니라, 거대한 문제를 해결 가능한 크기로 쪼개는 '분할 정복(Divide and Conquer)'의 핵심 도구임을 알아보겠습니다.
본론 1: 입력과 출력의 마법 상자
수학적 정의를 떠나, 공학적으로 함수는 '입력을 받아 처리를 거쳐 출력을 내놓는 블랙박스'입니다.
- 입력(Parameter): 커피 머신에 넣는 '원두'입니다. (인자값)
- 함수(Function): 원두를 갈고 물을 끓이는 '기계 장치'입니다. (코드 블록)
- 출력(Return): 완성되어 나오는 '에스프레소'입니다. (반환값)
우리가 printf()라는 함수를 쓸 때, 그 내부가 어떻게 구현되어 있는지 몰라도 글자가 출력되는 것처럼, 함수를 잘 설계하면 복잡한 내부 로직을 감추고 '기능'에만 집중할 수 있게 됩니다. 이를 추상화(Abstraction)라고 합니다.
본론 2: 유지보수, 고장 난 부품만 갈아 끼우기
NASA 시스템이 수십 년간 작동할 수 있는 비결은 철저한 모듈화 덕분입니다.
만약 코드 10,000줄이 한곳에 뭉쳐 있다면, 작은 오류 하나를 고치기 위해 전체를 다 뜯어봐야 합니다. 하지만 기능을 함수별로 쪼개 놓았다면? '엔진 점화' 기능에 문제가 생기면 ignite_engine() 함수만 열어서 수리하면 됩니다. 다른 코드는 건드릴 필요가 없습니다.
"한 번 작성하고, 여러 곳에서 쓴다(Reusability)." 이것이 효율적인 코딩의 제1원칙입니다. 똑같은 코드를 복사-붙여넣기 하고 있다면, 당장 함수로 묶으십시오.
본론 3: 함수 호출과 스택 메모리의 관계
지난 4편에서 다룬 '스택(Stack) 메모리'를 기억하시나요? 함수가 컴퓨터 내부에서 어떻게 작동하는지 알면 그 원리가 더 명확해집니다.
함수를 호출한다는 것은, 스택이라는 탑 위에 '스택 프레임(Stack Frame)'이라는 새로운 블록을 쌓는 행위입니다.
- 함수가 시작되면: 스택에 전용 공간(지역 변수 등)이 생깁니다.
- 함수가 끝나면(Return): 스택에서 그 공간이 즉시 삭제(Pop)됩니다.
함수 안에서 만든 변수가 함수 밖에서 사라지는 이유가 바로 이 물리적인 스택 구조 때문입니다. 이 원리를 이해해야 변수의 생명 주기(Scope)를 정확히 다룰 수 있습니다.
결론: 아키텍트(설계자)의 관점을 가져라
코딩을 처음 배울 때는 문법(Syntax)에 집중하지만, 고수가 될수록 구조(Structure)에 집중합니다. 함수는 그 구조를 만드는 가장 기본적인 벽돌입니다.
여러분의 코드를 남에게 보여줄 때, 주절주절 설명하지 않아도 함수 이름만 보고 "아, 여기서 데이터를 가져와서, 여기서 가공하고, 여기서 저장하는구나"라고 흐름이 읽혀야 합니다. 그것이 잘 설계된 소프트웨어입니다.
다음 [Part 9. 구조체(Structure)] 편에서는, 서로 다른 종류의 데이터(이름, 나이, 키 등)를 하나의 패키지로 묶어서 관리하는, 객체 지향의 시초가 되는 기술에 대해 알아보겠습니다.