본문 바로가기
[ C언어 ]/- C언어 문법공부

C언어 15장(함수, 재귀함수, 사용자 정의 함수, 표준 함수, main 함수, return)

by MRG 2020. 5. 6.
728x90
반응형
728x90

▣ 안녕하세요 ^^
저번장에 숙제는 해보셨나요?
배열에 대해서 진행했습니다.
이제 우리는 배열을 활용하여 여러 문자들과 숫자들을 가지고와 코딩할 수 있게 되었네요.
그럼 오늘은 함수에 대해서 배워보겠습니다.



▣ 먼저 함수란 무엇일까요?
우리가 수학 공부를 할 때 함수라는 말을 많이 듣고 사용했을 겁니다.

 

출저 : 위키백과

 

▣ 자 이렇게 함수를 우리가 과거에 마술상자? 요술상자? 같은 걸로 설명을 들었을 텐데요.
저는 그렇게 들었습니다. ^^;;
그때는 저도 거의 이해하지는 못했습니다. ^^;;
그냥 우리가 저 그림을 보고 쉽게 생각해보겠습니다.
우리가 값을 넣으면 저렇게 함수 원형 안에서 연산이 되고 결과를 준다.라고 생각하시면 될꺼같습니다.
진짜 그렇습니다.

 

 

▣ 자 함수를 한번 만들어보겠습니다. 
우리가 int main(void) { }를 사용했습니다.
이건 표준 함수라고 합니다.
표준 라이브러리 등등 말이 있는데,
쉽게 기본적으로 제공되는 함수들이라고 생각하시면 될꺼같습니다.



▣ 하지만 이번에는 사용자 정의 함수, 우리가 직접 함수를 만들어보겠습니다.
저 위에 있는 코드처럼 printf를 하는 함수를 만들어보겠습니다.
그런 다음에 프로그램에 시작인 main함수 안에 저 함수를 정의해주면
printf 결과가 나오게 됩니다.
main으로 시작해서 순차적으로 작동한다.
아주 간단한 원리입니다.



▣ 그런데 함수에 위치가 main함수보다 위에 있으니깐 좀 헷갈립니다.
프로그램은 분명 제가 순차적으로 작동한다고 했는데 말이죠.
그럼 이렇게 한번 바꿔보겠습니다.

 

 

▣ 함수를 내려놓고 디버깅을 해보면 오류가 나오게 됩니다.
왜 그럴까요?
간단하게 생각해보겠습니다.
제가 이야기했듯이 프로그램은 순차적으로 작동합니다. 
그럼 위에서부터 진행하겠죠?
#include를 전처리기를 진행하고 
main함수를 시작합니다.
그리고 순차적으로 작동하다가 Function이라는 함수를 실행하려고 하는데.
이 함수가 무엇인지 알 수 없습니다.
왜냐? 
프로그램은 순차적으로 작동하기 때문이죠.
컴퓨터가 저 함수는 무엇인지 모르고
정의되어 있지 않다고 경고를 주게 됩니다.
그럼 어떻게 해결해야 할까요?

 

 

▣ 네 번호를 적어서 이야기해보겠습니다.
이렇게 1번 줄에 우리가 변수를 선언한 것과 동일하게 선언을 해주면 됩니다.
그럼 1번 함수가 있어라고 컴퓨터한테 이야기를 해주면 
경고를 주지 않고 다음으로 순차적으로 작동하겠죠?
그런 다음에 밑에 정의된 함수까지 작동하고 안녕하세요를 출력하게 되고 프로그램이 끝납니다.
쉽게 생각해서 우리가 변수 선언과 정의를 생각해보면 될꺼같습니다.

 

▣ 우리가 이렇게 number라는 변수 안에 10을 대입했습니다.
그럼 바로 디버깅을 하면 오류가 나오게 됩니다.
왜냐 선언을 하지 않았기 때문에 어디에 대입을 해야 하는지 모르겠죠?

 

▣ 이렇게 위에 int라는 형식에 number라는 이름에 변수를 선언해라고 이야기를 하고
number을 대입을 해야 어디에 대입을 할지 알고 대입을 하게 됩니다.
컴퓨터는 사람이 아니기 때문에 꼭 선언을 먼저 진행해줘야 합니다.
제가 자꾸 이야기 이야기하는데 비유입니다. ^^;;

 

▣ 자 이번에는 숫자를 주면 그 숫자를 더해주는 함수를 만들어보겠습니다.
먼저 코드를 작성해주세요.
제가 하나하나 설명해드리겠습니다.
저는 Sum이라는 함수를 만들었습니다.
그런데 왜 이렇게 함수를 만드는지 조금 헷갈리시죠?
제가 먼저 함수를 만드는 방법에 대해서 다시 설명해드리겠습니다.

 

 

▣ 함수에는 반환할 자료형을 먼저 적어줍니다.
우리가 변수를 만들 때 자료형을 적는 것과 동일합니다. 하지만
우리가 위에서 함수를 표현한 그림을 봤을 때 상자 안에 넣고 그 안에서 연산을 하고 다시 값을 돌려주죠?
그 값을 돌려줄 값을 어떤 형식으로 줄지 결정한다고 생각하시면 될꺼같습니다.



그런 다음에 함수에 이름을 적습니다.
그리고 () 괄호를 넣습니다.



함수를 구분하려면 이렇게 () 이름 옆에 괄호가 있으면 함수입니다.
printf()도 함수겠죠?



그리고 우리가 값을 받아올 매개변수(인수)를 적어줍니다.
이렇게 어떤 자료형인지 어떤 변수로 복사 둘지를 정해줍니다.
복사라고 왜 표현한지는 메모리를 배우면 아실 겁니다.
우선 그냥 이렇게만 이해해주세요.



그리고 안에 함수에 원형을 만들어줍니다.
함수 상자 안에 있는 연산을 원형이라고 생각하시면 되겠습니다.
그리고 return은 반환할 값을 적어줍니다.
우리가 main함수를 사용할 때 return을 사용했죠??
return 내가 호출한 그곳에 다시 값을 돌려준다고 생각하시면 됩니다.



▣ 자 이렇게 함수 만들기를 설명했는데요.
이것도 이해를 안 하시고 넘어가시면 안 됩니다.
꼭 직접 코딩을 해서 저렇게 해석을 한번 해보세요.

 

 

 

▣ 자 이렇게 조금 그림이 이상하지만
프로그램이 어떻게 작동하는지를 번호로 하나하나 해석해보겠습니다.
# 전처리기는 제외하고 프로그램이 시작하면 



프로그램에 시작인 함수 main를 시작하겠죠?
그런 다음에 2번 변수를 선언해줍니다.
그리고 3번 sum변수 안에 Sum함수에 반환 값을 저장해줍니다.



▣ 소문자 대문자 s를 구분했습니다.
그래야 변수인지 함수인지를 할 수 있으니깐요.
보통 함수 이름은 대문자로 시작합니다.



그럼 4번 Sum함수로 가겠죠?
10과 20 각각 Sum함수에 매개변수(인수)를 가져옵니다.
그리고 6번 함수 안에 있는 변수를 선언해주고 7번 더한 값을 반환해줍니다.
그럼 main함수에 있는 sum 변수에 반환 값이 들어가겠죠?
그리고 8번 9번이 진행이 되고 프로그램이 끝납니다. 



▣ 자 그럼 이번에는 여러분들 차례입니다.
값을 다 바꾸셔서 곱하기를 할 수 있게 함수를 만들어주세요.
그리고 위에서처럼 직접 노트에 적어서 어떻게 프로그램이 작동하는지 번호를 쓰고 파악하고 
결과를 확인해주세요.
이걸 이해한 다음에 다음을 진행해주세요.

 

 

▣ 자 이렇게 값에 의한 호출을(call by value)라고 합니다.
이건 그냥 알아두세요^^
용어가 중요한 게 아니니깐요.



▣ 자 여기서 미션!!!
밑에 있는 코딩을 보지 말고.
직접 함수를 사용해서 int형 a와 b 변수를 선언 및 정의를 하신 다음에
둘에 값이 교환되는 함수를 만들어보세요. 
a값에는 b에 값이 b에 값에는 a가 교환되는 겁니다.



꼭 직접 해보시고 30분 동안 고민해서 정말 안되면 
밑에 있는 걸 참고해주세요.

 

 

▣ 저는 이렇게 두 가지 코딩을 진행했습니다.
이게 정답은 아닙니다.
다른 방법을 사용하셔도 됩니다.



저는 Swap이라는 함수와 main함수 각각 교환을 해보려고 만들었습니다.
하지만 먼가 결과가 이상하죠?
분명 Swap에서 값을 바꿨는데 전혀 바뀌지 않았습니다.
그리고 main함수에서는 바뀌었습니다.
자 이 부분이 정말 중요한데요.

 

 

 


▣ 자 이 예시를 보겠습니다.
제가 Swap를 함수에서 a와 b에 값을 변경했습니다.
그런데 main함수에서 printf함수로 결과를 봤더니 변숫값이 하나도 안 바뀐 걸 볼 수 있습니다.
이건 제가 주석에 넣어놨지만 함수가 끝나면 지역변수는 소멸되게 됩니다.
소멸이라는 말이 좀 이상하긴 한데 그 값이 없어진다 그렇게 이해해주시면 될꺼같습니다.
자 지역변수와 전역 변수에 대해 알아보겠습니다.



▣ 지역변수는 딱 그 지역에서만 사용이 가능합니다.
서울이면 서울에서 부산이면 부산에서만 딱 그 지역에서만 사용이 가능합니다.
전역 변수는 전체에서 사용이 가능합니다.
서울이 아닌 대한민국을 전역 변수라고 생각하시면 되겠네요.



그렇기 때문에 함수가 각각 다른 서로에 지역변수를 가지고 있는 겁니다.
그래서 Swap() 함수에서 지역변수를 바꿨지만 함수가 return에서 끝났기 때문에
main함수한테 영향을 주지 않습니다.

 

▣ 자 이렇게 코딩을 해보면 다르게 나오게 됩니다.
디버깅해보면 지역과 전역에 차이를 보실 수 있습니다.
함수를 벗어나서 사용한 변수가 전역 변수인데 모든 함수에 동일하게 사용이 가능합니다.
맨 위에 있는 변수를 이야기합니다. ^^ 
제가 주석으로 표시해두었죠?



▣ 그럼 이런 질문을 하실 수 있을 겁니다.
모두 다 전역 변수를 사용하면 되는 게 아닌가라는 말이죠
그런데 그건 프로그램이나 게임을 만들 때 아시겠지만,
상황에 따라 다른 부분입니다.



상수와 변수를 사용하는 부분에서도 말씀드렸듯이
모두 다 변수를 공유하면 나중에 오류가 났을 때,
다시 보고 읽고 고칠 때 
중요한 변숫값일 경우 등등
여러 상황을 고려해서 사용해야 합니다.



이건 게임을 만들 때 제가 자세하게 다루도록 하고
지금 이야기하는 건 별로 와 닿지 않을 거 같습니다.
우선 내가 상황에 맞게 딱 이 함수에서만 아니면
다른 함수에서 건드리면 안 되는 변수일 경우 
지역변수를 사용하고 
딱 한 가지만 필요한 값이고 어떤 변수에서도 이름과 값이 겹치치 않을 경우
모두 다 공유해도 될 경우에만 전역 변수를 사용하시는게 좋습니다.



▣ 이건 말보다 직접 코드를 작성해보세요.
지역변수와 전역변수를 구분해서 이해하시는 것 너무 중요합니다.
예를 들어 내가 playerHP를 전역 변수로 했는데
다른 곳에서 잘못 playerHP변수에 값을 떨어뜨리는 코드를 했다고 생각해봅시다.
아무것도 안 닿았는데 대미지가 달고 있어요...
어? 이거 왜 이러지라고 생각하고 멘붕이 오게 됩니다.
이런 실수를 저도 많이 했기 때문이죠^^;;
그렇기 때문에 직접 사용해보세요.



▣ 그리고 여기서 중요한 건 지역변수 전역 변수 등을 자세하게 설명하려면 
스택, 데이터 등 메모리에 대한 부분도  배워야 하니 이건 따로 장을 나눠서 공부해보겠습니다.



그럼 어떻게 전역 변수를 사용하지 않고 
지역변수를 다른 함수에서 값을 바꿀 수 있을까요?
그건 우리가 변수에서 배운 바로 주소를 활용하면 됩니다.

 

 

 

▣ 이렇게 포인터를 사용하면 됩니다.
포인터는 주소에 변수를 생각하시면 될꺼같은데,
이 부분도 제가 따로 다루도록 하겠습니다.



주소 값을 전달해서 그 주소를 찾아가서 직접 값을 바꿨다고 생각해주세요.
포인터에 대한 부분은 따로 진행하겠습니다.
우선 이렇게도 할 수 있구나를 기억해주세요.



▣ 그리고 포인터를 진행하려면 제가 변수와 scanf_s에서 했던 
개념들을 꼭 꼼꼼하게 공부해주세요.
아니면 포인터에서 포기하게 됩니다.^^;;
많은 분들이 그렇더라고요 ^^;;
그러니 꼭 공부해주세요.

 

 

▣ 자 마지막으로 이렇게 코딩을 만들어보겠습니다.
제가 두 가지를 이야기를 하려고 코드를 작성했는데요.



▣ 첫 번째 함수에서도 마찬가지 조건문을 넣어서 사용할 수 있습니다.
이런 식으로 말이죠. 
당연히 반복문도 가능합니다.
그런데 Swap 조건문에 안에 Swap 또 함수가 들어있죠?



▣ 이걸 재귀 함수라고 합니다.
함수 안에 함수를 사용한다라고 생각하시면 될꺼같습니다.
자기가 자기를 사용하는 거죠... ㅋㅋ



그럼 홀수일 경우에 
다시 Swap함수를 호출해서 다시 작동하게 하면 이런 식으로 결과가 나옵니다.



▣ 그런데 재귀 함수를 사용하실 때 주의해야 할 건
재귀 함수를 너무 남발하면 코드가 너무 복잡해진다라는 점 꼭 기억해주세요.
코딩을 읽는 것도 쉽지 않습니다. ^^;;



▣ 자 이 부분도 직접 조건문을 만들어서 재귀 함수를 사용해주세요.
꼭 직접 해보셔야 합니다.



▣ 자 그럼 함수는 언제 사용하고 만드나요?라는 질문이 있을 겁니다.
머 프로그램하시는 분들 마다 다르지만, 
반복되는 작업을 묶을 때 사용하기도 하고,
역할에 따라 함수로 묶기도 하고
코드를 좀 더 간결하게 만들 때 함수로 묶기도 합니다.



▣ 그리고 더 여러 상황이 있기 때문에
꼭 좋은 강사님들과 선생님들 자료와 영상들 보시면서 
같이 공부해주세요.
모두 다 노하우가 다르기 때문이죠.
이 부분은 너무 중요합니다.
제 블로그가 모든 정답은 아닙니다.
또한 다른 사람에 자료들도 정답은 아닙니다.
정답은 여러분들이 만들어가는 겁니다.
꼭 기억해주세요!!!



▣ 자 오늘은 함수를 배웠습니다.
우리가 표준 함수는 계속 사용했지만 직접 우리가 정의한 함수는 오늘이 처음이었습니다.
점점 더 어려워지고 있지만,
지금까지 꼼꼼하게 읽고 제가 말한 숙제들을 꾸준하게 하셨다면
그래도 이해하는 데는 어렵지 않으셨을 거라 생각합니다.
혹시 이해가 안 되거나
궁금하신 사항 그리고 필요한 코딩을 공부할 게 있으시면
댓글 남겨주세요 ^^



▣ 그럼 숙제는 저 위에 있는 것들을 다 해보고
우리가 반복문을 활용해서 만들었던 숫자게임을 함수를 이용해서 만들어주세요.
배열도 꼭 같이 사용해주시고요.



그럼 다음장에서 뵙겠습니다



▣ 포기하지 마세요!! 저도 했습니다!!! 파이팅!!!

728x90
반응형

댓글