Ch5. Functions - part 2 - Natural Language Processing Lab., Korea
Download
Report
Transcript Ch5. Functions - part 2 - Natural Language Processing Lab., Korea
5.11 Storage Classes (저장영역 부류)
C의 모든 변수와 함수는 두 가지 속성을 가진다
타입, 저장영역 부류
저장영역 부류는 네 가지임.
자동, 외부, 레지스터, 정적
대응되는 키워드
이중, 레지스터만 제외하고 모두 RAM(혹은 가상 메모리)에 만들
어진다.
auto
extern
register
static
참고사항
함수의 경우, extern과 static 키워드만 쓸 수 있다.
Natural Language Processing Lab, Korea University
26
5.11 Storage Classes (저장영역 부류)
auto (자동 변수)
함수의 몸체에서 아무런 키워드 없이 선언된 변수
굳이 이 키워드를 쓰지 않아도 자동 변수가 된다.
블록 안에서 선언된 변수는 역시 묵시적으로 자동변수임
블록을 들어갈 때, 자동 변수들을 위해 메모리가 할당되고,
블록을 빠져나갈 때, 자동 변수가 할당 받은 메모리는 회수된다
자동변수가 될 수 있는 것: 앞에서 배운 지역 (local) 변수
예제
auto int i
int i
Natural Language Processing Lab, Korea University
27
5.11 Storage Classes (저장영역 부류)
extern(외부 변수)
키워드 extern의 역할
함수 밖에서 선언된 변수
프로그램이 종료될 때까지 메모리에 계속 남아 있게 됨
다른 소스 파일 간에 정보를 건낼 때 자주 사용
extern이 될 수 있는 변수: 앞에서 배운 전역변수
컴파일러에게 "이 변수를 현재 파일이나 다른 파일에서 찾아라"라고 지시하는
것
예제
/* In file file1.c */
#include <stdio.h>
int a=1,b=2;
int f(void);
/*전역 변수로 선언*/
int main(void)
{
printf("%3d\n",f());
printf("%3d%3d%3d\n",a,b);
return 0;
}
Natural Language Processing Lab, Korea University
/* In file file2.c */
int f(void)
{
extern int a; /*a는 외부변수 */
int b;
a=b=4;
return (a+b);
}
28
5.11 Storage Classes (저장영역 부류)
register (레지스터 변수)
register 키워드의 역할
레지스터(CPU 안에 들어 있는 메모리. RAM보다 고속임)를 저장영역
으로 사용하는 변수
“이 변수를 (가능하다면) 레지스터에 저장되도록 하라”고 지시하는
것
한정된 자원으로 인해 저장이 불가능하면, 저절로 자동 변수가 됨
이러한 변수는 사용되기 바로 전에 선언하는 것이 좋음
예제
register int i;
register i
register float f;
for (i=0; i<LIMIT; i++) { … }
참고 사항(알아도 되고 몰라도 되는 내용)
register로 선언하지 않은 변수라도, 컴파일러의 최적화에 따라 자동으
로 레지스터 변수가 되는 경우가 있다.
이것을
막아주는
키워드가
volatile임.
Natural Language
Processing
Lab, Korea
University
29
5.11 Storage Classes (저장영역 부류)
static (정적 변수)
블록에서 선언된 변수가 프로그램이 끝날 때까지 그 값을 계속
유지하도록 할 때 사용.
선언문에 속지 말 것: 미리 초기화되어 있음. 함수호출 시엔 그
문장이 실행되지 않는다.
예제:
정적변수를 사용하지 않는 함수와 정적변수를 사용하는 함수
void f(void)
{
int count=0;
if (++count%10==0) {
…
}
}
Natural Language Processing Lab, Korea University
void f(void)
{
static int count=0;
if (++count%10==0) {
…
}
}
30
5.12 Static External Variables (정적 외부 변수)
정적 외부 변수란:
외부변수(전역변수) 앞에 static 키워드를 붙여서 선언한 변수
이렇게 만들어진 변수의 유효범위는, 자신이 선언된 해당 소스파일로
한정된다.
정적 외부변수의 특징:
다른 소스 파일의 함수는 이 변수를 사용할 수 없다. extern을 써서 끌
어올 수 없다는 이야기.
다른 소스 파일에서 같은 이름을 사용하더라도 컴파일에러가 안 남.
정적 외부변수의 용도:
외부에 공개하지 않을 변수를 선언할 때
Natural Language Processing Lab, Korea University
31
5.12 Static External Variables (정적 외부 변수)
예제: 컴파일이 잘 되는지 확인해 볼 것
/* In file file1.c */
#include <stdio.h>
int a=1,b=2;
int f(void);
static int c;
int main(void)
{
printf("%3d\n",f());
printf("%3d%3d%3d\n",a,b);
return 0;
}
Natural Language Processing Lab, Korea University
/* In file file2.c */
int f(void)
{
extern int a;
int b;
a=b=4;
return (a+b+c);
}
32
5.13 Default Initialization(기본값 초기화)
원칙:
외부 변수와 정적 변수는 프로그래머가 초기화하지 않아도 시
스템에 의해 0으로 초기화됨
자동 변수와 레지스터 변수는 일반적으로 시스템에 의해 초기
화되지 않음
개발도구, 개발환경에 따라 조금씩 다르다.
Natural Language Processing Lab, Korea University
33
5.14 Recursion(재귀)
재귀란?
어떤 함수가 직접이든 간접이든 자기 자신을 호출하는 것
재귀 함수의 예
int sum(int n)
{
if (n<=1) return n;
else return n+sum(n-1);
}
/*n<=1일 때까지 sum이 호출된다*/
/*sum(n) > sum(n-1) >… > sum(1) */
int factorial(int n)
{
if (n<=1) return 1;
/*n<=1일 때까지 factorial이 호출된다*/
else return n*factorial(n-1);
}
Natural Language Processing Lab, Korea University
34
5.14 Recursion(재귀)
#include <stdio.h>
/*입력받은 한 줄을 거꾸로 출력하는 프로그램*/
void wrt_it(void)
{
int c;
if ((c=getchar()) != '\n') wrt_it();
putchar(c);
}
int main(void)
{
printf("Input a line: ");
wrt_it();
printf("\n\n");
return 0;
}
Natural Language Processing Lab, Korea University
35
5.14 Recursion(재귀)
재귀 함수의 가장 기본적인 패턴: Tail Recursion (꼬리재귀)
Tail Recursion의 일반적인 구성요소:
재귀 종료 코드
재귀 수행 코드
Tail Recursion의 제어 흐름
변수를 검사하여 종료 조건에 맞는지 아닌지를 검사함
종료 조건 만족:
– 재귀 호출 중단. 필요한 값을 리턴
종료 조건 안 만족:
– 재귀 호출 수행. 이때 종료조건으로 한 걸음씩 다가가게 변수
를 조정한다.
Natural Language Processing Lab, Korea University
36
5.14 Recursion(재귀)
Tail Recursion의 예제
int sum(int n)
{
if (n <= 1)
return n;
else
return (n + sum(n - 1));
}
Natural Language Processing Lab, Korea University
/* 종료 조건 검사*/
/* 재귀 종료*/
/* 재귀 수행 */
37