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