공부했던 자료 정리하는 용도입니다.
재배포, 수정하지 마세요.
함수
- 함수의 정의
- 함수의 유형
* 여러 개의 return문이 존재하는 경우 - 재귀 함수
변수의 존재 기간과 접근 범위
- 지역 변수(Local Variable), 자동 변수(automatic variable)
- 전역 변수
- static변수
- register 변수
함수
함수의 정의
[반환형] [함수이름] ([자료형 인자이름1], [자료형 인자이름2] ...)
{
// 함수 호출시 실행될 문장
return [리턴값] ; // 반환값이 있는 경우
}
한번 정의된 함수는 몇 번이고 호출이 가능하고, 함수 안에서 함수를 호출하는 것도 가능하다. (``main``을 포함한 모든 함수는 조건 및 상황에 관계없이 다른 함수를 호출할 수 있다.) 함수가 호출되면 호출된 함수의 영역으로 실행의 흐름이 이동하고, 호출된 함수가 반환되면 다시 함수를 호출했던 함수가 이어서 실행된다.
- 반환형 : 함수 호출이 끝나고 반환될 리턴 값의 자료형
반환 값이 없을 경우 ##void##라고 한다. - 함수 이름 : 함수의 이름 지정
- 자료형 인자 이름 : 함수를 호출할 때 전달되는 인자의 자료형과 이름을 지정한다. 후에 함수를 호출할 때 정의된 인자 개수에 맞춰 매개변수를 넣어야 한다. 인자가 없는 경우 ##void##라고 하고 함수 호출 시 인자를 전달하면 안 된다.
- return(선택) : 반환 값이 있을 때 사용한다.
반환형이 ##void##인 함수에도 ##return##문을 사용할 수 있다. 사용하면 값을 반환하지 않고 함수를 빠져나간다는 의미!
함수의 유형
함수는 인자와 반환 값의 유무에 따라 여러 가지 유형으로 나눌 수 있다. (인자의 수는 여러 개가 될 수 있지만 반환 값은 하나이므로 주의한다.)
함수의 유형
- 전달 인자 O, 반환 값 O
- 전달 인자 O, 반환 값 X
- 전달 인자 X, 반환 값 O
- 전달 인자 X, 반환 값 X
#include <stdio.h>
// 함수 정의
// 1, 전달인자 O, 반환값 O
int Add(int num1, int num2)
{
return num1 + num2;
}
// 2, 전달인자 O, 반환값 X
void ShowAddResult(int num)
{
printf("덧셈결과 출력 : %d \n", num);
}
// 3, 전달인자 X, 반환값 O
int ReadNum(void)
{
int num;
scanf("%d", &num);
return num;
}
// 4, 전달인자 X, 반환값 X
void HowToUseThisProg(void)
{
printf("두 개의 정수를 입력하면 덧셈 결과가 출력됩니다. \n");
printf("두 개의 정수 입력 : ");
}
// main 함수
int main(void)
{
int result, num1, num2;
HowToUseThisProg();
num1 = ReadNum();
num2 = ReadNum();
result = Add(num1, num2);
ShowAddResult(result);
return 0;
}
4가지 유형의 함수를 선언하고 ``main``함수에서 호출하는 예시이다.
#include <stdio.h>
// 함수 선언
int Add(int num1, int num2); //int Add(int, int);도 가능
void ShowAddResult(int num); //void ShowAddResult(int);도 가능
int ReadNum(void);
void HowToUseThisProg(void);
// main 함수
int main(void)
{
int result, num1, num2;
HowToUseThisProg();
num1 = ReadNum();
num2 = ReadNum();
result = Add(num1, num2);
ShowAddResult(result);
return 0;
}
// 함수 정의
int Add(int num1, int num2)
{
return num1 + num2;
}
void ShowAddResult(int num)
{
printf("덧셈결과 출력 : %d \n", num);
}
int ReadNum(void)
{
int num;
scanf("%d", &num);
return num;
}
void HowToUseThisProg(void)
{
printf("두 개의 정수를 입력하면 덧셈 결과가 출력됩니다. \n");
printf("두 개의 정수 입력 : ");
}
함수를 ``main``함수 아래에 정의하는 경우 ``main``함수 위에 함수 선언을 해놓지 않으면 컴파일 에러를 일으킨다. 함수의 선언에는 매개변수의 개수 및 자료형 정보만 포함되면 되기 때문에 ``int Increment(int)``같이 매개변수의 이름을 생략하고 선언하는 것도 가능하다.
+ 여러 개의 return문이 존재하는 경우
int MaxNumberCompare(int num1, int num2)
{
if(num1 > num2)
return num1;
else
return num2;
}
함수의 위치에 상관없이 ``return``문이 올 수 있고 ``return``문이 여러 개 오는 것도 가능하다. 그러나 위와 같이 ``return``문이 여러 개인 경우에도 최종적으로 함수를 빠져나가면서 반환되는 값은 하나뿐이다!
재귀 함수
#include <stdio.h>
int Factorial(int n)
{
//재귀함수 탈출 조건
if(n == 0)
return 1;
else
return n * Factorial(n - 1);
}
int main(void)
{
printf("1! = %d\n", Factorial(1));
printf("2! = %d\n", Factorial(2));
printf("3! = %d\n", Factorial(3));
printf("4! = %d\n", Factorial(4));
printf("9! = %d\n", Factorial(9));
}
함수 내에서 자기 자신을 다시 호출하는 함수를 의미한다. 위의 예시 같은 경우 ``Factorial`` 함수를 실행하는 중간에 다시 ``Factorial`` 함수가 호출되면 함수의 복사본을 하나 더 만들어서 복사본을 실행하게 된다.(함수를 구성하는 명령문은 CPU로 복사되어 실행된다.) 그래서 함수가 완료되지 않은 상태에서 다시 호출하는 것이 가능한 것이다.
변수의 존재 기간과 접근 범위
변수의 종류
- 지역 변수
- 전역 변수
- static 변수
- register 변수
지역 변수(Local Variable), 자동 변수(automatic variable)
- 지역변수의 지역은 중괄호 `` { } ``에 의해 형성되는 영역을 의미하고, 이 안에 선언되는 변수들을 모두 지역 변수라고한다.
- 지역변수는 'stack' 메모리 영역에 할당된다.
- 선언된 지역 내에서만 유효하고, 해당 지역을 벗어나면 자동으로 소멸된다.
- 지역변수는 선언된 지역 내에서만 유효하기 때문에 선언된 지역이 다르면 이름이 같아도 문제가 되지 않는다.
- 반복문이나 조건문에도 선언 가능하다.
- 함수의 매개변수도 지역변수의 일종이다.
선언문이 실행될 때 메모리 공간에 할당되었다가 선언문이 존재하는 함수가 반환되면 메모리에서 소멸된다.
전역 변수
- 지역변수와 달리 중괄호 `` { } ``내에 선언하지 않는다.
- 프로그램 전체 영역 어디서든 접근이 가능한 변수이다.
- 프로그램 시작과 동시에 메모리 공간에 할당되어 종료 시까지 존재한다.
- 별도의 값으로 초기화하지 않으면 @@0@@으로 초기화된다.
- 많이 사용하면 프로그램이 복잡해지기 때문에 사용에 신중해야 한다.
static 변수
- 지역변수에 ``static``을 붙여서 만든다.
- 지역변수와 전역 변수의 특성을 동시에 가진다
* 지역 변수 특성
선언된 함수 내에서만 접근 가능
* 전역 변수 특성
처음 1회만 초기화되고 프로그램 종료 시까지 메모리 공간에 존재(전역 변수와 동일한 시기에 할당/소멸)
초기화하지 않으면 전역 변수처럼 @@0@@으로 초기화
register 변수
- 지역변수에 ``register``를 붙여서 만든다. (전역 변수에는 추가할 수 X)
- 선언하면 해당 변수가 CPU 내의 레지스터에 저장될 확률이 높아진다.
컴파일러는 이 선언을 힌트로 하여 레지스터의 활용 여부를 결정한다. 최종 결정은 컴파일러가 내리며, 반대로 아무 선언을 안 해도 컴파일러가 레지스터에 할당해야겠다고 판단하면 레지스터에 할당된다.
'기타 > C' 카테고리의 다른 글
[C] 포인터 (0) | 2020.05.05 |
---|---|
[C] 배열 (1차원 배열, 다차원 배열, 가변 길이 배열) (1) | 2020.04.28 |
[C] 조건문, 반복문 (0) | 2020.04.16 |
[C] printf, scanf 함수 (0) | 2020.04.09 |
[C] 자료형 변환 (0) | 2020.04.08 |