C언어 스터디. 함수 제작, 함수반환, Call-by-Value, 프로토타입, 재귀함수
31. 함수 생성
#include <stdio.h>
int main() {
printf("Hello, World!");
}
간단한 게임 프로그램으로 함수생성을 이해해보자
- 함수 이름은 의미가 명확히 드러나도록 정의하기
- 중괄호 안에서 선언된 변수는 밖에서 쓸 수 없다. --> 그래서 전역변수로 빼주는 게 필요함.
- 매개변수: 지역변수와 마찬가지로 함수 내에서만 사용이 가능함. 매개변수 cost는 함수 buyItem 내에서만 선언되어 있음. 즉 매개변수 cost를 main함수에서 사용할 수 없음.
- 매개변수 두 개 이상 사용 가능
#include <stdio.h>
int itemCnt = 0; //전역변수
int money = 100;
int cost;
void buyItem() { //함수이름은 명확히 드러나도록!
itemCnt++;
money -= cost;
printf("아이템을 구매했습니다.\n");
printf(" 아이템의 개수: %d\n", itemCnt);
printf(" 잔액: %d\n", money);
}
int main() {
//중괄호 안에서 선언된 변수는 밖에서 쓸 수 없다.
//int itemCnt = 0;
//int money = 100; 밖으로 빼주면 된다.
cost = 30;
buyItem();
cost = 50;
buyItem();
}
- 매개변수를 사용한 예시
#include <stdio.h>
int itemCnt = 0; //전역변수
int money = 100;
void buyItem(int cost) {// cost는 매개변수
itemCnt++;
money -= cost;
printf("아이템을 구매했습니다.\n");
printf(" 아이템의 개수: %d\n", itemCnt);
printf(" 잔액: %d\n", money);
}
int main() {
buyItem(30);
buyItem(50);
}
32. 함수의 반환
return: 돌려주다 , 반환하다 라는 의미.
printf도 출력된 글자값을 반환함. EX) int a = printf("aaaa")하면 printf("%d\n", a)의 값은 4
#include <stdio.h>
//return: 반환
//두 개의 매개변수(정수)의 합을 반환하는 함수
int plus(int a, int b) {
return a + b;
}
int main() {
int sum = plus(3, 4);
printf("%d\n", sum);
}
★참고: int main()은 특정한 return값이 없으면 그냥 return 0을 함.
- 두 가지를 반환하는 함수는 불가능하다. 왜냐면 return을 한번이라도 하면 함수값이 바로 결정됨. 첫번째 return 밑에 무엇을 써도 적용되지 않는다.
int plus(int a, int b) {
printf("first\n")
return a + b; //여기까지만 값이 반환됨.
printf("second\n")
return a - b;
}
- 게임 프로그램 함수로 return(반환)값 이해하기
#include <stdio.h>
int itemCnt = 0; //전역변수
int money = 100;
int buyItem(int cost, int cnt) {// 매개변수 cost 비용, cnt 상품 묶음 개수
if (money >= cost) {
itemCnt += cnt;
money -= cost;
printf("아이템을 구매했습니다.\n");
printf(" 아이템의 개수: %d\n", itemCnt);
printf(" 잔액: %d\n", money);
return 0;
}
else {
printf("잔액이 부족합니다. \n");
return -1;
}
}
int main() {
int result = buyItem(30, 5); //result에 return 0이 반환되고
int result = (50, 7); //result에 return -1이 반환
}
#include <stdio.h>
int itemCnt = 0; //전역변수
int money = 100;
int buyItem(int cost, int cnt) {// 매개변수 cost 비용, cnt 상품 묶음 개수
if (money < cost) { //잔액이 부족할 때 부터 점검. 부족하면 여기서 함수 종료되고 -1반환
printf("잔액이 부족합니다.\n");
return -1;
}
//잔액이 충분할 때
itemCnt += cnt;
money -= cost;
printf("아이템을 구매했습니다.\n");
printf(" 아이템의 개수: %d\n", itemCnt);
printf(" 잔액: %d\n", money);
return 0;
}
int main() {
buyItem(30, 5);
buyItem(50, 7);
}
33. call-by-value 와 call-by-reference
call-by-value (값에 의한 호출)
call-by-reference (참조에 의한 호출)
// 들어가기 전: 값 바꾸기 예시
#include <stdio.h>
int main() {
int a, b;
scanf("%d %d", &a, &b);
int tmp = a;
a = b;
b = tmp;
}
- 두 개의 값을 변환하는 함수 swap() 만들기
잘못된 예시
#include <stdio.h>
//오류
void swap(int x, int y) {
int tmp = x;
x = y;
y = tmp;
}
int main() {
int a, b;
scanf("%d %d", &a, &b);
swap(a, b);
printf("a = %d, b = %d\n", a, b);
}
// a=2 b=3 x=2 y=3인데 swap함수 종료된 후 반환되는 값이 없음.
//이 문제를 해결하려면? 포인터
☆swap 함수가 값을 반환하게 만들려면 포인터를 사용해야함
//포인터를 사용해서 값을 변환하는 함수 만들기
#include <stdio.h>
void swap(int *x, int *y) {
int tmp = *x;
*x = *y;
*y = tmp;
} // a=2, y=3, x=포인터(a의 주소) y=포인터(b의 주소), tmp는 값
int main() {
int a, b;
scanf("%d %d", &a, &b);
swap(a, b);
printf("a = %d, b = %d\n", a, b);
}
34. 프로토타입
prototype: 원형, 시제품 ,함수가 어떻게 생겼는 지 간단히 적어주는 것
EX) drawSquare함수
#include <stdio.h>
//걷기
void walk(int distance) { //매개변수 distance
printf("%dcm를 걸었습니다.\n", distance);
}
//돌기
void rotate(int angle) {
printf("%d도 회전했습니다.\n", angle);
}
//사각형 그리기
void drawSquare() {
for (int i = 1; i <= 4; i++) {
walk(10);
rotate(90);
}
}
int main() {
drawSquare();
}
만약에 여기서 int main()이 void drawSquare()보다 위로 가면 오류가 남(순서를 바꿀 수 없다는 문제)
--> 프로토타입으로 이 문제를 해결 가능 : 함수가 무엇인 지 알려만 주고 정의는 미루는 것.
#include <stdio.h>
//프로토타입
void walk(int distance); //아 함수가 있구나. walk는 void형이고 매개변수는 distance를 쓴다.
void rotate(int angle);
void drawSquare(); //선언(함수이름, 형, 매개변수만 적고 구현은 안함)
int main() {
drawSquare();
}
void walk(int distance) { //매개변수 distance
printf("%dcm를 걸었습니다.\n", distance);
}
//돌기
void rotate(int angle) {
printf("%d도 회전했습니다.\n", angle);
}
//사각형 그리기
void drawSquare() {
for (int i = 1; i <= 4; i++) {
walk(10);
rotate(90);
}
}
프로토타입의 장점
1) 함수가 함수를 호출하는 상황에서 신경을 쓸 필요 X
2) 함수들의 순서를 신경 쓸 필요 X
3) 프로토타입만 봐도 한눈에 함수들을 파악 가능O
35. 재귀함수
- 재귀 함수(recursion, rec): 자기자신의 정의 안에 자기자신이 또 들어가는 것.
재귀함수 구조:
#include <stdio.h>
void rec() {
}
int main() {
rec();
}
//재귀인데 무한 반복
#include <stdio.h>
void rec(int n) {
printf("n =%d\n", n);
rec(n + 1);
}
int main() {
rec(1);
}
//종결조건을 추가한 재귀함수
#include <stdio.h>
void rec(int n) {
if (n > 5) return; //종결조건, n이 5까지만 실행됨. 5보다 크면 return 0;
printf("n =%d\n", n);
rec(n + 1);
}
int main() {
rec(1);
}
- 재귀함수를 사용해 팩토리얼 만들기
#include <stdio.h>
//팩토리얼을 만들어보자!
//n!=n * (n-1)!
int fact(int n) {
if (n == 1) return 1;
return n * fact(n - 1);
}
int main() {
printf("%d\n", fact(5));
}