오늘 스택(Stack)을 구현하면서 함수 코드를 뜯어보다가 문득 이런 생각이 들었습니다.
"아니, 어떤 건 앞에 void가 붙고, 어떤 건 괄호 안에 아무것도 없고... 이거 기준이 뭐야?"
저처럼 C언어 입문 단계에서 함수의 생김새 때문에 머리 쥐어뜯고 계신 분들을 위해,
오늘 제가 스스로 묻고 답하며 정리한 내용을 공유합니다!
1. 오늘의 스택(Stack) 설계도 (헤더파일)
C
typedef int element;
element stack[STACK_SIZE];
void push(element item); // 데이터 입력
element pop(void); // 데이터 삭제
element peek(void); // 데이터 보기
void printStack(void); // 전체 출력
2. "왜 누구는 void고, 누구는 element야?" (반환형의 비밀)
가장 헷갈렸던 부분인데, 함수 이름 맨 앞에 붙는 건 "함수가 일을 다 끝내고 나한테 돌려줄 결과물의 종류" 더라고요.
- void push(element item)
- 내 생각: "야, 이 데이터(item) 스택에 좀 넣어놔."
- 결과: 넣으라고 시켰으니 끝입니다. 나한테 다시 돌려줄 게 없죠? 그래서 '없음'을 뜻하는 void가 붙습니다.
- element pop(void)
- 내 생각: "스택 맨 위에 있는 거 하나 꺼내서 나 줘봐."
- 결과: 함수가 데이터를 꺼내서 나한테 건네줘야 합니다. 그 건네주는 데이터의 정체가 element(int)니까 앞에 붙는 거죠.
💡 한 줄 요약: 함수 맨 앞은 결과물(Return)의 자리! 없으면 void, 있으면 그 데이터의 타입을 쓴다.
3. 매개변수(Parameter)의 정확한 정의
괄호 () 안에 들어가는 매개변수(Parameter)는 쉽게 말해 "함수 외부와 내부를 잇는 통로"입니다.
- push(element item): 데이터를 넣으려면 '무엇을' 넣을지가 있어야겠죠? 그래서 item이라는 준비물이 필요합니다. (입력값 O)
- pop(void): 꺼낼 때는 준비물이 딱히 필요 없어요. 규칙상 그냥 제일 위에 있는 걸 꺼내면 되니까요. 그래서 **'준비물 없음'**의 **void**를 씁니다. (입력값 X)
4. 출력과 반환의 차이
printStack 함수를 보면서 "원소를 출력하려면 원소값을 받아와야 하는데 왜 void지?"라고 생각했었는데요. 이게 완전 오해였습니다.
- 출력(Print): 그냥 모니터 화면에 글자를 뿌리는 것. (사람 눈에 보여주기용)
- 반환(Return): 함수가 계산한 결과값을 프로그램 내부의 다른 변수에게 전달하는 것. (컴퓨터가 다음 계산에 쓰기용)
**void printStack(void)**는 스택을 쭉 훑으면서 화면에 보여주기만 하고 끝나는 '서비스형' 함수라, 프로그램에 값을 돌려줄 필요가 없어서 void인 것이었습니다!
5. 최종 요약
| 함수 | 준비물(In) | 결과물(Out) | 하는 일 |
| push | 데이터 있음 | 없음(void) | 스택에 때려 넣기 |
| pop | 없음(void) | 데이터 있음 | 꺼내서 나한테 주기 |
| peek | 없음(void) | 데이터 있음 | 안 꺼내고 슬쩍 보기 |
| 없음(void) | 없음(void) | 화면에 예쁘게 보여주기 |
마치며
처음엔 void라는 단어만 봐도 울렁거렸는데, "함수가 나한테 뭘 주는지(앞), 내가 함수한테 뭘 주는지(괄호)"만 생각하니까
코드가 훨씬 만만해 보이네요. 저랑 비슷한 고민을 하셨던 분들께 도움이 되었길 바랍니다!