PowerPoint 프레젠테이션

Download Report

Transcript PowerPoint 프레젠테이션

제7장 함수
문봉근
YES C 제 7 장 함수
1/96
제7장 함수
7.1 매크로함수
7.2 표준함수
7.3 사용자정의함수
7.4 변수의 스토리지 클래스 통용범위
7.5 함수간의 데이터 전달
7.6 재귀함수
7.7 main() 함수와 매개변수
YES C 제 7 장 함수
2/96
함수단위로 프로그램을 했을 때의 장점
① 불필요한 반복을 피할 수 있으며 메모리를 절약할 수
있다.
② 프로그램의 모듈화(modularize)가 가능하여, 이해
(readability)가 쉽고, 수정이 용이하다. 함수들을 재
사용(reusability)할 수 있다.
③ 주 모듈(main함수)에는 각 기능별로 구성된 함수이
름으로 구성하는 것이 바람직하며 이로 인한 전체 프
로그램의 구조와 이해도가 빠르다.
④ 그 함수기능과 매개변수만을 이용하여 그 프로그램
을 호출하여 사용할 수 있다.(encapsulation)
YES C 제 7 장 함수
3/96
7.1 매크로 함수
• 매크로함수는 함수의 형태는 띠고 있지만 실
제로 함수는 아니다.
• 매크로 선언문인 ‘#define'을 사용하여 상수,
함수(수식)를 선언할 수 있다.
– #define macro_name(par1[,par2,...]) [macro_body]
• 매크로 확장 : 매크로 함수가 프로그램 중에
사용될 때 전처리기는 매크로명과 매개변수를
지우고, 그 위치에 매개변수를 인수 텍스트로
대체한 매크로 몸체를 삽입한다.
• 매크로함수를 인라인함수(inline function)라
부르기도 한다.
YES C 제 7 장 함수
4/96
예제 7.1 macro 함수의 정의와 인용
#define square(t) ((t)*(t))
#define max(u,v) ((u)>(v)?(u):(v))
....
y = a + square(x+3) / square(x-3)
iput(max(x+3), square(y)));
=> 매크로 확장
y = a + ((x+3)*(x+3)) / ((x-3)*(x-3));
iput(((x+3)>((y)*(y)) ? (x+3) : ((y)*(y))));
YES C 제 7 장 함수
5/96
예제 7.2 매크로 함수를 사용하는 경우 예기치 않은 에
러가 발생할 경우.
#define square(t) t*t
#define max(u,v) ((u)>(v)?(u):(v));
....
y = a + square(x+3) / square(x-3)
iput(max(x, y));
=> 매크로 확장
y = a + x+3*x+3 / x-3*x-3;
iput(((x)>(y) ? (x) : (y)););
YES C 제 7 장 함수
6/96
예제 7.3 매크로 선언은 제대로 되었지만 프로그램 중
에 잘못 사용하는 경우.
#define square(x) ((x)*(x))
...
a = 3;
y = square(++a);
=> 매크로 확장
y = (++a)*(++a);
YES C 제 7 장 함수
7/96
7.2 표준 함수
• 모든 표준 C 라이브러리의 구성요소는
하나이상의 표준 헤더 파일(header file)
에 정의되어 있다.
• 프로그램에서 라이브러리(library)의 구
성요소를 사용하기 위해서는 관련된 표
준 헤더의 이름을 include 지시자를 이
용하여 포함시켜야 한다.
YES C 제 7 장 함수
8/96
7.2.1 표준 C 헤더의 사용
• include 지시자를 사용하여 표준헤더의 이름
을 사용한다.
• #include <stdio.h>
/* 입출력 기능포함 */
• 표준헤더를 2개 이상 사용할 때는 순서에 관
계없이 include 할 수 있다.
• 키워드와 같은 이름의 매크로(include)를 정
의할 수 없으며, 표준헤더는 다른 표준헤더에
포함될 수 없다.
YES C 제 7 장 함수
9/96
예제 7.4 표준함수 중 time(), srand()를 사용하여, 난
수를 발생시키는 프로그램.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void main(void) {
int i=1;
unsigned int seed;
seed = time(0);
srand(seed);
while( i <= 5 ) {
printf(" 난수 발생 결과 : %d\n", rand());
i++;
}
}
YES C 제 7 장 함수
10/96
예제 7.5 표준 수학함수 중 삼각함수 sin(x)를 이용하여
0°부터 360°까지의 sin값을 10°간격으로 구하고, *를 이용
하여 sin graph를 나타내는 프로그램.
삼각함수(sin, cos, tan 등)에서 사용되는 괄호 안의 인수
는 radian을 사용하며, radian = ( 각도 * π ) / 180 이다.
#include <stdio.h>
#include <math.h>
#include <conio.h>
void main(void)
{
int i, j;
double pi=3.141593, sine;
for(i=0; i<=360; i+=10) {
sine = sin( (float)i * pi / 180);
printf("sin(%3d)=%5.2f ", i, sine);
for(j=0; j<= (int)(sine*30+30); j++)
printf(" ");
printf("*\n");
if( (i+10) % 190 == 0) getch();
11/96
YES C} 제 7 장 함수
}
7.3 사용자 정의 함수
• 함수의 구성요소
– ① 함수의 계산 결과를 되돌려 받는 함수의 type
– ② 함수이름을 나타내는 함수명
– ③ 함수로 전달될 데이터의 변수 선언 부분인 매
개변수 리스트
– ④ 함수 내부에 필요한 변수의 선언
– ⑤ 각종 명령문을 수행할 함수의 본체
– ⑥ 함수를 호출한 곳으로 되돌아갈 return문
YES C 제 7 장 함수
12/96
7.3.1 사용자정의함수 문법
반환데이터형 함수명(매개변수리스트)
매개변수형_선언;
{
지역변수선언;
함수의_본체;
return(수식) ;
/* 반환문 : 여기서 수식의 데이터형은
반환데이터형과 같다 */
}
YES C 제 7 장 함수
13/96
예제 7.6 사용자 정의함수의 기본 호출 프로그램.
#include <stdio.h>
int sub_func(int); /* 함수의 protype(원형)선언 */
void main(void)
{
int i;
for (i=1; i<=5; ++i)
sub_func(i); /*호출함수(caller) :
sub_func() 함수호출*/
}
int sub_func(k) /* 피 호출함수(callee) */
int k;
/* 매개변수(parameter)의 형 선언 */
{
int j;
/* 지역변수 선언 */
/* 함수 본체 */
for (j=0; j<=k; ++j)
printf("test 번호 : %d\n", j);
printf("\n");
return(k);
/* 함수호출 부분으로 돌아가는 반환문 */
} YES C 제 7 장 함수
14/96
7.3.2 함수의 호출
• 함수를 사용하기 위해서는 호출(call)을 하여야만 한
다.
• 결과를 돌려 받지 않는 경우에는 return문은 생략할
수 있으며, 이 때에는 함수가 끝나면 원래의 호출함수
로 돌아간다.
• 함수의 계산결과를 되돌려 받기 위해서는 한 개 이상
의 반환(return)문이 있어야 한다.
• 호출과 반환에 있어서 데이터형을 반드시 일치시켜야
한다.
• 함수는 스스로 수행될 수 없으며, 다른 프로그램에서
호출하지 않으면 수행되지 않는다.
• 함수는 식의 일부로써 사용할 수 있고, 호출 자체가
하나의 문장을 이루기도 한다.
YES C 제 7 장 함수
15/96
예제 7.7 함수를 수식의 일부로 호출하여 사용하는 방법.
#include <stdio.h>
int max(int[], int);
void main(void)
{
int j, x[10]={34, 56, 33, 23, 99, 33, 45, 67, 89, 9};
j = max(x, 10);
/* 식의 일부로서 함수를 호출 */
printf("최대값 : %d\n", j);
}
int max(int y[], int n)
{
int i, mx=y[0];
for (i=1; i<n; ++i)
if(mx < y[i]) mx = y[i];
return(mx);
}
YES C 제 7 장 함수
16/96
7.3.3 함수의 결과 반환
• 호출한 함수로 문장의 흐름을 돌려주고, 돌려줄 때 연산
결과를 함수에 전달하기 위해서 return문을 사용한다.
• return문 뒤에 되돌려줄 변수나 수식을 기술한다. return문
뒤에는 괄호를 사용하여도 되며, 생략할 수도 있다.
• 함수의 형을 void로 선언했을 경우에는 return문이 없을
수도 있다.
• 함수의 형이 void가 아니고, 반환되는 값이 있다면 최소한
한 개 이상의 return문이 있어야 하며, 반환 값의 형(type)
과 함수의 형은 반드시 일치해야 한다.
YES C 제 7 장 함수
17/96
예제 7.8 함수의 값을 반환할 때 함수의 데이터형과 일
치하여야 한다.
float add_numbers( float n1, float n2 )
{
return n1 + n2;
/* 적절하다. */
return 6;
/* 부적절하다. 데이터형이 다르다.*/
return 6.0;
/* 적절하다. */
}
YES C 제 7 장 함수
18/96
예제 7.9 함수에서 반환값이 없는 경우의 간단한 함수를
포함하는 프로그램
• #include <stdio.h>
• void print_message( void );
/* ANSI C 함수 원형 */
• void print_message( void )
• {
•
printf("이것은 print_message함수에 의해 호출된 모듈이다.\n");
• }
• void main(void)
• {
•
print_message(); /* 함수 호출 */
• }
YES C 제 7 장 함수
19/96
예제 7.10 일반 함수를 이용한 factorial(!)을 계산하는
프로그램.
•
•
#include <stdio.h>
void calc_factorial( int );
•
•
•
•
•
•
•
void calc_factorial( int n )
{
int i, factorial_number = 1;
for( i = 1; i <= n; ++i )
factorial_number *= i;
printf("%d 팩토리얼은 %d이다.\n", n, factorial_number );
}
•
•
•
•
•
•
•
void main(void)
{
int number = 0;
printf("숫자를 입력하시오. : ");
scanf("%d", &number );
calc_factorial( number );
} YES C 제 7 장 함수
/* 함수 원형 */
20/96
예제 7.11 상황에 따라서 여러 개의 return문이 필요한
경우의 함수 프로그램.
/* 어떤 달의 마지막이 며칠인지 계산, 여러 개의 return문이 있음
*/
#include <stdio.h>
#include <stdlib.h>
int last_day(int, int);
void main(void)
{
int year, month;
printf("년도를 입력하시오 : "); scanf("%d", &year);
printf("월을 입력하시오 : "); scanf("%d", &month);
printf("%d년 %d월은 마지막날이 %d일 입니다.\n",
year, month, last_day(year, month));
}
YES C 제 7 장 함수
21/96
예제 7.11 (계속)
/* 어떤 달의 마지막이 며칠인지 계산,
여러 개의 return문이 있음 */
int last_day(int y, int m) /* y:년, m:월 */
{
if( m == 2 ) { /*2월일 경우 28일인지 29일인지 계산 */
if(y%400 == 0 || (y%100 != 0 && y % 4 == 0))
return(29);
else return(28);
}
else if(m == 4 || m == 6 || m == 9 || m == 11 )
return(30); /*4,6,9,11월은 30을 돌려줌 */
else return(31); /* 나머지는 31을 돌려줌 */
}
YES C 제 7 장 함수
22/96
예제 7.12 여러 개의 반환문을 사용하는 다른 예
• int validate_input( char command )
• {
•
switch( command ) {
•
case '+' :
•
case '-' : return 1;
•
case '*' :
•
case '/' : return 2;
•
default : return 0;
•
}
• }
YES C 제 7 장 함수
23/96
예제 7.13 두 개의 인수를 전달하여, 그 두 수의 곱의 결
과를 반환하는 프로그램
•
•
#include <stdio.h>
int calc_result( int, int );
•
•
•
•
•
•
int calc_result( int numb1, int numb2 )
{
auto int result;
result = numb1 * numb2;
return result;
}
•
•
•
•
•
•
void main(void)
{
int digit1 = 10, digit2 = 30, answer = 0;
answer = calc_result( digit1, digit2 );
printf("%d * %d = %d\n", digit1, digit2, answer );
}
YES C 제 7 장 함수
/* 함수 원형 */
24/96
예제 7.14 long 형을 되돌려주는 factorial 함수
•
•
#include <stdio.h>
long factorial(int); /* 함수 원형 */
•
•
•
•
•
•
•
•
long factorial(int n) /* long형을 되돌리는 함수 */
{
int i;
long product = 1l;
for (i = 2; i <= n; i++)
product *= i;
return product;
}
•
•
•
•
•
•
•
•
•
void main(void)
{
int num;
long fact;
for (num = 1; num <= 10; num++) {
fact = factorial(num); /* factorial 함수 호출뒤 fact에 대입 */
printf("%2d! = %8ld\n", num, fact);
}
}
YES C 제 7 장 함수
25/96
예제 7.15 함수의 여러 가지 사용 방법.
#include <stdio.h>
int sum(int, int); /* 함수 원형 */
void a();
void main(void)
{
int s;
a();
/* a 함수 호출 */
sum(10,20);
/* sum 함수를 호출 */
s = sum(20,60); /* sum 함수를 호출한 후 반환 값을 s에 저
장 */
printf("sum from 20 to 60 = %d\n",s);
printf("sum from 10 to 100 = %d\n",sum(10,100));
}
YES C 제 7 장 함수
26/96
예제 7.15 (계속)
void a()
{
printf("This is function test.\n");
printf("Now in function a()\n");
}
int sum(int a, int b)
/* 정수형 변수 2개를 받아 정수형을 반환하는 함수 */
{
int i, s = 0;
printf("Now in function b()\n");
for (i = a; i <= b; i++)
s = s + i;
return s; /* s의 값을 호출한 함수에게 반환한다 */
}
YES C 제 7 장 함수
27/96
예제 7.16 양수면 1, 음수면 -1, 0이면 0을 출력하는 프
로그램. 이 예제는 while문을 사용하여 Ctrl + Z(EOF)를
누를 때까지 무한루프를 도는 프로그램이다.
#include <stdio.h>
#include <conio.h>
int sign(int);
/* prototype 선언 */
void main(void)
{
int a;
printf("Ctrl + Z = exit\n");
printf("input(a)=>");
while(scanf("%d",&a) != EOF) {
printf(" %d\n",sign(a));
printf("Ctrl + Z = exit\n");
printf("input(a)=>");
}
}
int sign(int x)
{
return ( (x>0) ? 1 : ( (x==0) ? 0 : -1) );
} YES C 제 7 장 함수
28/96
7.3.4 함수 원형(prototype)
• 함수의 원형(Function Prototypes)은 반환되는
데이터형 검사와 함수 호출에 대한 파라미터 검사
를 하기 위해서 사용된다.
• C 프로그램은 일반적으로 여러 개의 다른 소스파
일들로 독립적으로 분리되어 컴파일되고, 실행 프
로그램을 생성하기 위해서 이들을 묶어서 링크함
으로서 에러가 발생할 가능성이 있다.
• 이 충돌을 피하기 위해 ANSI C는 함수 원형을 선
언한다.
YES C 제 7 장 함수
29/96
예제 7.17 여러 개의~
•
•
•
•
•
/* 소스파일 add.c */
void add_up( int numbers[20] )
{
....
}
•
•
•
•
•
•
•
•
/* 소스파일 mainline.c */
static float values[] = { 10.2, 32.1, 0.006, 31.08 };
void main(void)
{
float result;
...
result = add_up( values );
}
YES C 제 7 장 함수
30/96
7.3.5 함수의 형
• C 언어는 함수 자체가 값을 반환하는 함수와 반환하지 않
는 함수가 있다.
• 값을 반환하는 함수는 변수선언에서 처럼 type을 선언할
수 있다. 이때 type은 C에서 정의된 기본형(int, float,
char, pointer 등)과 사용자 정의형(struct, union 등)을 모
두 사용할 수 있다.
• 반환할 데이터 형(type)을 선언하지 않을 경우 정수(int)형
으로 간주한다.
• 함수의 반환 값이 없을 경우에는 void형으로 선언한다.
• 값의 반환이 있는 함수의 경우에는 주고받는 매개변수의
형태에 주의하여 사용해야 한다.
YES C 제 7 장 함수
31/96
문법-정수형을 반환하는 경우의 함수의 선언
int func(매개변수들)
{
int x;
함수 본문(function body);
return(x);
/* 여기서 x의 값이 정수형이라는 뜻이다. */
}
YES C 제 7 장 함수
32/96
문법-반환 type을 선언하지 않은 경우 : 정수형
func(매개변수들)
{
int x;
함수 본문(function body);
return(x); /* 여기서 x의 값이 정수형이라는
뜻이다. */
}
YES C 제 7 장 함수
33/96
문법-반환하는 변수가 없는 경우 : void
void func(매개변수들)
{
int x;
함수 본문(function body);
return;
/* 반환하는 값이 없으므로 return을 생략할
수 있다*/
}
YES C 제 7 장 함수
34/96
예제 7.18 입력된 수를 넘겨받아 원하는 수만큼 "*"를 출
력하는 프로그램 예제
/* void형 함수 */
#include <stdio.h>
void print_char(char c, int n)
{
int i;
for (i = 1; i <= n; i++)
printf(" %c",c);
}
void main(void)
{
int i, n;
printf("Input N -> ");
scanf("%d",&n);
for (i = 1; i <= n; i++) {
print_char(' ',n - i);
print_char('*',2 * i - 1);
putchar('\n');
}
for (i = 1; i <= n - 1; i++) {
print_char(' ',i);
print_char('*',2 * n - 2 * i - 1);
putchar('\n');
YES }
C 제 7 장 함수
}
35/96
예제 7.19 영어의 모음, 자음, 대문자, 소문자, 숫자를 카운트하는
함수를 만들어서 이용한 프로그램
•
•
•
•
•
•
#include <stdio.h>
int is_vowel(char);
int is_alphabet(char);
int is_upper(char);
int is_lower(char);
int is_digit(char);
•
•
•
•
•
•
•
•
•
void main(void)
{
char c;
int vno = 0;
/* 모음의 갯수를 기억할 변수 */
int cno = 0;
/* 자음의 갯수를 기억할 변수 */
int uno = 0;
/* 대문자의 갯수를 기억할 변수 */
int lno = 0;
/* 소문자의 갯수를 기억할 변수 */
int dno = 0;
/* 숫자의 갯수를 기억할 변수 */
printf("문자열을 입력하시오 : Ctrl-Z (exit) ");
YES C 제 7 장 함수
36/96
예제 7.19 영어의 모음, 자음, 대문자, 소문자, 숫자를 카운트하는
함수를 만들어서 이용한 프로그램(계속)
•
printf("문자열을 입력하시오 : Ctrl-Z (exit) ");
•
•
•
•
•
•
•
•
•
•
•
•
while ((c = getchar()) != EOF) {
if (is_vowel(c))
/* 읽은 문자가 모음이면 */
++vno;
/* 모음 숫자를 하나 증가 */
else if (is_alphabet(c)) /* 모음이 아닌 알파벳이면(자음이면)*/
++cno;
/* 자음 숫자를 하나 증가 */
if (is_upper(c))
/* 읽은 문자가 대문자이면 */
++uno;
/* 대문자 숫자를 하나 증가 */
else if (is_lower(c))
/* 대문자가 아닌 소문자이면 */
++lno;
/* 소문자 숫자를 하나 증가 */
else if (is_digit(c))
/* 읽은 것이 숫자면 */
++dno;
/* 숫자 카운트를 하나 증가 */
}
•
•
•
•
•
•
printf(" Number of Vowels : %d\n",vno);
printf("Number of Consonants : %d\n",cno);
printf("Number of Uppercases : %d\n",uno);
printf("Number of Lowercases : %d\n",lno);
printf(" Number of Digits : %d\n",dno);
}
YES C 제 7 장 함수
37/96
예제 7.19 영어의 모음, 자음, 대문자, 소문자, 숫자를 카운트하는
함수를 만들어서 이용한 프로그램(계속)
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
is_vowel(char c) /* 주어진 문자가 영문 모음인지 판단하는 함수 */
{
switch (c) {
case 'a': case 'e': case 'i': case 'o': case 'u':
case 'A': case 'E': case 'I': case 'O':
case 'U': return (1); /* 문자가 모음인 경우 1을 계산 결과로 산출 */
default : return (0); /* 모음이 아니므로 0을 계산 결과로 산출 */
}
}
is_alphabet(char c) /* 주어진 문자가 영문 알파벳인지 판단하는 함수 */
{
return (is_upper(c) || is_lower(c));
}
is_upper(char c) /* 주어진 문자가 대문자인지 판단하는 함수 */
{
return (c >= 'A' && c <= 'Z');
}
is_lower(char c) /* 주어진 문자가 소문자인지 판단하는 함수 */
{
return (c >= 'a' && c <= 'z');
}
is_digit(char c) /* 주어진 문자가 숫자인지 판단하는 함수 */
{
return (c >= '0' && c <= '9');
}
YES C 제 7 장 함수
38/96
7.3.6 함수명 (function name)
• 함수를 대표하며, 함수명은 변수선언과 같이 키워
드가 아닌 고유함수명이어야 한다.
• 한 개의 프로그램에서 똑같은 함수명은 존재할 수
없다.
• 함수명을 만드는 규칙은 변수명을 만드는 규칙과
동일하며 문자열로써 구성된다.
• 첫 문자는 영대문자, 영소문자, _(underscore)중
의 하나로 시작하며, 나머지 문자는 숫자도 사용
할 수 있다.
• 함수명을 작명할 때는 그 함수가 어떤 동작을 하
는지를 분명히 나타내는 것이 좋다.
YES C 제 7 장 함수
39/96
예제 7.20 함수명을 작명할 때 정확한 의미를 부여하는 것이 좋다.
•
•
•
#include <stdio.h>
int *matrix_add(int *, int *);
/* prototype 선언*/
int *matrix_product(int *, int *);
/* prototype 선언*/
•
•
•
•
•
void main(void)
{
matrix_add();
/* matrix_add()함수 호출 */
matrix_product();
/* matrix_product()함수 호출 */
}
•
•
•
•
•
•
•
•
•
•
•
•
•
•
int *matrix_add(int *x, int *y) /* 함수명의 뜻을 정확하게... */
{
int *z;
printf("matrix_add()함수가 호출되었습니다.\n");
중략....
return *z;
}
int *matrix_product(int *x, int *y) /* 함수명의 뜻을 정확하게... */
{
int *z;
printf("matrix_product() 함수가 호출되었습니다.\n");
중략....
return *z;
}
YES C 제 7 장 함수
40/96
7.3.7 매개 변수 리스트와 매개 변수 형 선언
• 실인수 : 매개변수 중에서 main안의 호출함수에
있는 매개변수
• 가인수 : 피 호출함수의 매개변수를 가인수라 한
다.
• 실인수와 가인수의 매개변수의 이름은 달라도 상
관이 없으나 그 형은 같아야 한다.
• 가인수를 선언하는 방법은 2가지 형태가 있다.
• 만약에 매개변수가 필요하지 않을 경우 매개변수
리스트는 없다.
YES C 제 7 장 함수
41/96
main()
{
int i, j;
중략;
sum(i,j);
중략;
/* 변수선언 */
/* 호출함수 */
}
피호출함수
sum(x,y)
int x,y; /* 가인수 */
{
중략
}
YES C 제 7 장 함수
피호출함수
sum(int x, int y) /* 가인수 */
{
중략
}
42/96
7.4 변수의 스토리지 클래스 통용범위
• C 언어에서는 다양한 성질의 변수를 사용할 수 있
다.
• 프로그램의 전영역에 걸쳐서 사용할 수 있는 변수
가 있는 전역변수
• 변수가 선언되는 함수 안에서만 사용 가능한 지역
변수
• 변수가 프로그램의 어느 영역에서 사용가능 한가를
변수의 범위(scope)라 한다.
• 변수를 스택에 위치시킬 것인지, 정적영역(static
scope)에 위치시킬 것인지를 지정할 수 있다.
• 이와 같이 변수를 특정 메모리 영역에 할당하는 것
을
“Storage Class”라 한다.
43/96
YES C 제 7 장 함수
표 7.1 스토리지 클래스의 통용범위
선언장소
함수의 외부
함수의 내부
기억지정자
기억장소
수명
통용범위(scope)
없음
정적영역
불변
전 모듈의 전역
static
정적영역
불변
선언된 모듈의 전역
extern
다른 곳에서 정의된 외부 변수를 이 선언 이
후의 모듈의 전역에서 사용할 수 있음
auto 또는 없음
스택
소멸
선언된 블록 내
register
레지스터
또는 스택
소멸
선언된 블록 내
static
정적영역
불변
선언된 블록 내
extern
다른 곳에서 정의된 외부 변수를 이 선언 이
후의 모듈의 전역에서 사용할 수 있음
YES C 제 7 장 함수
44/96
7.4.1 자동변수
• 지금까지 명시를 하지 않고 main()함수나 특정한 함수 내
에서 한정적으로 사용하기 위하여 자동변수를 사용하였다.
• auto란 키워드를 사용하여 auto 변수를 선언을 하기도 하
지만 통상적으로 auto를 생략하고 프로그램 한다.
• 이를 지역변수(local variables)라 한다.
• 지역변수는 이들이 선언된 특정 함수 내에서만 존재한다.
• 이들은 다른 함수에게는 알려지지 않는다.
• 지역변수는 통상적으로 스택(stack)을 사용하여 구현된다.
• 지역변수를 만들었던 함수가 종료되면 지역변수는 존재하
지 않는다. 함수가 실행되거나, 호출될 때마다 지역변수는
재생성 된다.
YES C 제 7 장 함수
45/96
7.4.1 자동변수(계속)
• 함수 내에서 연산 결과를 기억할 임시변수가 필요할 때 사
용하며 지역변수를 사용하지 않아도 되는 경우는 생략할
수 있다.
• 지역변수는 그 함수 내에서만 사용가능하며 다른 함수에
서는 사용할 수 없다.
• 함수가 다르면 같은 변수명을 사용하더라도 전혀 다른 변
수로 인식을 한다.
• 물론 전역변수(global variable)의 경우는 모든 함수에서
선언하지 않고 사용할 수가 있으며 이 때에는 같은 값으로
사용된다.
• 전역변수와 같은 변수명을 어떤 함수에서 다시 선언하여
사용하는 경우에는 그 함수에서 선언한 변수가 우선적으
로 사용되며, 전역변수는 사용이 되지 않는다.
YES C 제 7 장 함수
46/96
예제 7.21 함수의 내부변수가 필요 없는 경우
#include <stdio.h>
int gcd(int, int); /* 함수원형 */
void main(void)
{
int i, j;
printf("최대 공약수를 구할 두 수를 입력하시오(i, j) : ");
scanf("%d, %d", &i, &j);
printf("%d와 %d의 최대공약수는 %d이다.\n",i,j,gcd(i,j));
}
/* 유클리드 호제법을 이용한 최대공약수 구하는 함수 */
int gcd(int x, int y)
{
/* 내부변수가 선언되지 않았다. */
while(x != y)
if (x > y ) x -= y;
else y -= x;
return x;
}
YES C 제 7 장 함수
47/96
예제 7.22 내부 변수가 필요한 경우/다른 함수에서 같은
이름의 변수를 사용한 경우
#include <stdio.h>
int max(int [], int); /* 함수원형 */
void main(void)
{
int i[10]={98, 84, 85, 96, 37, 48, 57, 27, 37, 48};
printf(" 배열 i에서 가장 큰 값은 %d이다.\n", max(i, 10));
}
int max(int x[], int y) /* 배열 요소 중 최대값을 구하는 함수 */
{
int temp_max, i; /* 내부변수가 선언되었다. */
temp_max = x[0];
/* main함수의 i변수와 여기서 선언된 i변수는
전혀 다른 별개의 변수로서 사용된다. */
for(i=1; i<y; i++)
if( x[i] > temp_max) temp_max = x[i];
return temp_max;
}
YES C 제 7 장 함수
48/96
7.4.2 전역변수
• 전역변수(global variables)는 프로그램에 포함된
모든 함수에 의해서 액세스될 수 있다.
• 전역변수는 모든 함수에게 알려져 있다.
• 함수가 재 호출되어도, 전역변수는 재 생성되지
않는다.
• 전역변수의 유효 범위는 변수가 어느 시점에서 선
언이 되었는가에 따라서 제한될 수 있다. 전역변
수는 선언 시점부터 현재의 소스파일의 끝까지 가
시적(visible)이다. 즉, 선언된 시점 이후부터 사용
가능하다.
• 전역변수는 일반적으로 프로그램의 첫 영역에 나
오며, 다른 함수들을 사용하기 전에 선언한다.
YES C 제 7 장 함수
49/96
예제 7.23 전역변수 선언을 사용하였을 경우 각각의 함
수에서 전역변수의 사용 예.
#include <stdio.h>
int add_numbers( void );
/* 함수 원형 */
/* 이들 전역변수들은 이 시점 이 후부터 access될 수 있다 */
int value1, value2, value3;
int add_numbers( void )
{
auto int result;
result = value1 + value2 + value3;
return result;
}
void main(void)
{
auto int result;
value1 = 10;
value2 = 20;
value3 = 30;
result = add_numbers();
printf(" %d + %d + %d = %d\n",
value1, value2, value3, result);
} YES C 제 7 장 함수
50/96
예제 7.24 전역변수와 지역변수가 같은 이름으로 선언된
경우
#include <stdio.h>
int max(int [], int);
int a, b;
/* 함수원형 */
/* 전역 변수로 선언되었다. */
void main(void)
{
int i[10]={98, 84, 85, 96, 37, 48, 57, 27, 37, 48};
printf(" 배열 i에서 가장 큰 값은 %d이다.\n", max(i, 10));
}
int max(int x[], int y)
/* 배열 요소 중 최대값을 구하는 함수 */
{
int temp_max=-32768, a;
/* 전역변수로 선언된 a를 지역변수로 다시 선언하면
전역변수와 지역변수는 별개의 변수로서 사용된다. */
for(a=0; a<y; a++)
if( x[a] > temp_max) temp_max = x[a];
return temp_max;
} YES C 제 7 장 함수
51/96
예제 7.25 extern 데이터 유형 변수 이름
#include <stdio.h>
void f1(void);
/* 함수 원형 */
void main(void)
{
extern int count;
int i;
i = count - 5;
++count;
f1();
printf("i = %d, count = %d\n", i ,count);
}
int count = 5;
void f1(void)
{
++count;
}
YES C 제 7 장 함수
52/96
예제 7.26 예제 7.25 프로그램에서 다음과 같이 main 앞
에 count를 정의하면 변수 선언을 할 필요가 없다.
#include <stdio.h>
void f1(void);
int count = 5;
void main(void)
{
int i;
i = count - 5;
++count;
f1();
printf("i = %d, count = %d\n",i,count);
}
void f1(void)
{
++count;
}
YES C 제 7 장 함수
53/96
예제 7.27 반면에 반드시 변수 선언을 해야만 하는 경우
가 있는데 이는 사용하고자 하는 변수가 다른 파일에 정의
되어 있는 경우이다.
/* filename : main.c
#include <stdio.h>
*/
void main(void)
{
extern int count;
int i = 5;
f1();
printf("i = %d, count = %d\n",i,count);
}
/* filename : f1.c
int count = 10;
void f1(void)
{
++count;
}
YES C 제 7 장 함수
*/
54/96
7.4.3 함수 내에서의 정적변수
• 함수 내에서의 정적변수(static variables)의 선언은 키워
드 static을 사용한다.
• 함수 내에서의 정적변수는 선언된 함수 내에서만 사용가
능하며 함수에서 프로그램의 흐름이 빠져나가더라도 계속
변수는 유지된다.
• 정적변수는 함수에서 처음 호출될 때 한번만 생성되고 한
번만 초기화되며, 함수에서 재 호출할 때 정적변수가 다시
생성되거나 초기화되지 않는다.
• 함수가 끝날 때, 변수는 여전히 정적영역에 존재한다. 그
러나 외부 함수에 의해 액세스되어 사용될 수는 없다.
• 자동변수는 정적변수와는 완전히 다르다. 자동변수는 함
수로 들어갈 때마다 만들어지고, 다시 초기화된다. 함수가
끝날 때 자동변수는 사라진다.
YES C 제 7 장 함수
55/96
예제 7.29 정적변수와 자동변수의 차이점을 보여주는 프
로그램.
#include <stdio.h>
void demo( void );
/* 함수 원형 */
void demo( void )
{
auto int avar = 0;
static int svar = 0;
printf("auto = %d, static = %d\n", avar, svar);
++avar;
++svar;
}
void main(void)
{
int i;
i = 0;
while( i < 3 ) {
demo();
i++;
}
} YES C 제 7 장 함수
56/96
예제 7.30 지역 static 변수와 auto 변수의 사용 예를 보
여주는 프로그램.
#include <stdio.h>
void test()
{
static int s_count;
/*static 메모리 유형은 초기화시키지 않았을 경우*/
int a_count = 0; /* 0의 값을 가진다 */
s_count++;
a_count++;
printf("static count = %2d\tauto count = %d\n",
s_count,a_count);
}
void main(void)
{
int i;
for (i = 0; i < 10; i++)
test();
} YES C 제 7 장 함수
57/96
7.4.4 함수 외부에서의 정적변수
• 전역 static 메모리 유형의 변수(global static
variables)들은 철저하게 자신이 정의된 위치부터
그 파일의 끝까지가 자신의 동작 범위가 된다.
• 따라서 그 외의 부분에서는 변수 선언을 해도 이
변수를 사용할 수 없다. 즉, 소스 파일이 다를 경
우에는 사용할 수 없다.
• 전역변수를 선언할 때는 static을 사용하는 경우
와 사용하지 않는 경우가 있다. static을 사용할
경우와 사용하지 않을 경우의 차이는 위의 표 7.1
을 참고하기 바란다.
YES C 제 7 장 함수
58/96
예제 7.31 static 전역 변수의 사용 예를 보여주는 프로
그램.
#include <stdio.h>
void no_access( void ); /* 함수원형 */
void all_access( void );
static int n2;
/* n2는 이 시점이후부터 알려지게 된다. */
void no_access( void )
{
n1 = 10;
/* 부적절, n1은 아직 알 수 없다. */
n2 = 5;
/* 적절 */
}
static int n1;
/* n1은 이 시점에서부터 알려진다. */
void all_access( void )
{
n1 = 10;
/* 적절 */
n2 = 3;
/* 적절 */
}
YES C 제 7 장 함수
59/96
예제 7.32 전역 static 변수의 사용 예를 보여주는 프로그램.
•
#include <stdio.h>
•
•
•
void proc1(void);
int i = 10;
static int j = 3;
•
•
•
•
•
•
void main(void)
{
int k = 1;
printf("i = %d, j = %d, k = %d\n",i,j,k);
proc1();
}
•
•
•
char c = 'A';
static char d = 'B';
•
•
•
•
void proc1(void)
{
printf("%c%c\n",c,d);
}
YES C 제 7 장 함수
60/96
7.4.5 외부변수
• 외부변수(external variables)가 정의되기 이전에,
또는 다른 모듈에서 그 변수를 사용하고자 하는
경우에는 extern 선언을 하면 된다.
• C 언어에서는 소스 파일을 여러 개로 분할하여 컴
파일할 수 있다. 이것을 분할 컴파일이라 하는데,
그 분할된 컴파일 하나를 단위로 할 때 “모듈
(module)”이라 한다.
YES C 제 7 장 함수
61/96
7.4.6 레지스터변수
• 레지스터변수는 메모리영역을 CPU의 레지스터
에 배당하는 것 이외에는 자동변수와 동일한 성격
을 가진다.
• 레지스터변수는 모든 경우에 int형으로 사용된다.
• 사용빈도가 높은 변수를 레지스터변수로 할당시
켜주면 대단히 빠른 처리 속도를 이용할 수 있다.
• 레지스터 변수를 너무 많이 쓰게 되면 오히려 프
로그램의 속도를 저하시키는 경우가 발생할 수도
있다.
• 보통 한 두개의 변수를 쓰는 경우는 고려할 만하
다.
YES C 제 7 장 함수
62/96
7.5 함수간의 데이터 전달
• 함수는 구조상 값을 하나만 반환하지만 배열과 같이 하나
이상의 값을 반환하는 경우도 있다.
• 이와 같은 경우에는 여러 개의 인수를 반환하는 것이 아니
라 인수의 주소를 포인터를 이용하여 전달해 준다. => 주소
를 반환함으로써 여러 개의 값을 반환할 수 있도록 한다.
• 인수의 값을 함수에 전달하여 프로그램을 실행하는 과정 :
값에 의한 전달(call by value)
• 인수 값 대신에 인수의 주소번지를 함수에 전달하여 그 주
소를 공유하면서 사용을 하는 방법 : 주소에 의한 전달(call
by reference)
• Call by reference의 경우에는 호출된 함수에서 값을 변경
시키면 주소를 공유하기 때문에 호출함수의 인수 값도 변경
된다는
점을 유의해야 한다.
63/96
YES C 제 7 장 함수
7.5.1 값에 의한 전달
• 값에 의한 전달(call by value)은 c 언어에서 기본
적인 데이터 전달 방식이다.
• 실인수(actual parameter)와 가인수(formal
parameter)가 별도의 기억 장소를 갖고, 함수가
호출되면 실인수 값을 가인수에 복사한다.
• 데이터 전달이 끝나면 실인수와 가인수간의 상호
관계는 없으며 독립적이다.
• 피 호출함수에서 가인수의 값을 변경하더라도 실
인수에는 전혀 영향을 미치지 않는 별개의 메모리
장소를 차지한다.
YES C 제 7 장 함수
64/96
main()
{
int a, b;
…
f=func1(a,b);
…
}
a
b
인수전달
서로 독립적이다.
func1(int i, int j)
{
결과값 반환
…
return(x);
}
YES C 제 7 장 함수
i
j
65/96
예제 7.33 main 함수에서의 값의 변화와 함수에서의 값
의 변화를 보여주는 프로그램.
#include <stdio.h>
void swap (int, int); /* 함수의 prototype 선언 */
void main(void)
{
int x, y;
printf("두 변수 x, y를 입력하시오 : ");
scanf("%d,%d", &x, &y);
printf("함수 실행 전 변수 값 : x = %d, y = %d\n", x, y);
swap(x, y); /* 단순히 함수만 호출 */
/* 실행결과를 되돌려 받지 않았으므로 x, y의 값의 변화는 없다.*/
printf("함수 실행 후 변수 값 : x = %d, y = %d\n", x, y);
}
void swap (int a, int b)
{
int t;
/* 지역 변수 */
/* a, b 변수는 함수 내에서만 사용된다 */
printf("함수내 교환 전 변수 값 : a = %d, b = %d\n",a,b);
a ^= b, b ^= a, a ^= b; /* XOR를 이용한 두 값의 교환 */
printf("함수내 교환 후 변수 값 : a = %d, b = %d\n",a,b);
66/96
} YES C 제 7 장 함수
예제 7.34 구의 부피를 구하는 프로그램을 함수로 작성하라.
•
•
# include <stdio.h>
float ball_volume(float);
•
•
•
•
•
•
•
void main(void)
{
float r;
printf("구의 반지름을 입력하시오 : “);
scanf("%f", &r);
printf("반지름 이 %5.1f일 때 공의 부피=%7.2f\n", r, ball_volume(r));
}
•
•
•
•
float ball_volume(float h)
{
return(4.0/3.0*3.14*h*h*h);
}
YES C 제 7 장 함수
/* 함수의 prototype 선언 */
67/96
7.5.2 주소에 의한 전달
• 주소에 의한 전달(call by reference)은 인수의 주
소(address)를 전달하는 방식이다.
• 주의할 점 : 호출 함수와 피 호출함수 간에 주소를
공유하기 때문에 기억된 값을 공유한다. 따라서
피 호출함수에서 값이 바뀌면 호출 함수의 인수
값이 같이 바뀐다.
• 함수의 인수로 변수의 주소를 이용할 때
– ① 함수의 실인수는 주소로 넘겨야 한다.
– ② 호출된 함수의 가인수는 포인터나 혹은 배열로 받는
다.
YES C 제 7 장 함수
68/96
main()
{
}
int a, b;
…
a
f=func1(&a,&b);
…
b
주소전달
참조
func1(int *i, int *j)
{
…
}
YES C 제 7 장 함수
i
&a
j
&b
69/96
예제 7.35 주소를 넘겨주었을 경우의 변수의 변화를 보
여주는 프로그램.
#include <stdio.h>
void swap(int *, int *); /* 함수 원형 */
void main(void)
{
int x = 15, y = 37;
printf("함수 실행 전 값 x = %d, y = %d\n", x, y);
swap(&x, &y);
printf("함수 실행 후 값 x = %d, y = %d\n", x, y);
}
void swap(int *a, int *b)
{
printf("함수 내 교환 전 a = %d, b = %d\n", *a, *b);
*a ^= *b, *b ^= *a, *a ^= *b;
/* XOR를 이용한 데이터 교환 */
printf("함수 내 교환 후 a = %d, b = %d\n", *a, *b);
}
YES C 제 7 장 함수
70/96
7.5.3 배열의 주소 전달
• 주소에 의한 전달 방식으로 배열의 시작 주소를
전달한다.
• 배열 크기에 관한 정보가 없기 때문에 프로그램
작성자가 크기를 알려주어야 한다.
– 배열의 마지막 요소에 어떤 특정 값으로 파악하는 방법.
– 배열의 크기를 인수로 전달하여 처리하는 방법.
YES C 제 7 장 함수
71/96
예제 7.36 배열을 함수에 넘겨주는 프로그램을 작성하라.
#include <stdio.h>
void sub_func1(int *data);
void sub_func2(int data[]);
void sub_func3(int data[], int n);
void main(void)
{
int a[10] = { 10, 20, 30, 40, 50, 60, 70, -1};
/*-1은 데이터의 끝*/
sub_func1(a);
/* 가인수를 포인터로 표현 */
sub_func2(a);
sub_func3(a, 7);
/* 배열의 크기를 인수로 전달 */
}
YES C 제 7 장 함수
72/96
예제 7.36 (계속)
void sub_func1(data)
int *data;
{
int sum = 0;
while(*data != -1) { /* 배열의 끝이 -1 */
sum += *data;
++data;
}
printf("sum = %d\n", sum);
}
void sub_func2(data)
/* 가인수를 배열로 표현
int data[];
{
int sum = 0, i ;
for (i = 0; data[i] != -1; ++i)
sum += data[i];
printf("sum = %d\n", sum);
}
YES C 제 7 장 함수
*/
73/96
예제 7.36 (계속)
void sub_func3(data, n)
/* 배열 크기의 정보를 인수로 넘겨줌 */
int data[], n;
{
int sum = 0, i;
for (i=0; i<n; ++i)
sum += data[i];
printf("sum = %d\n", sum);
}
YES C 제 7 장 함수
74/96
7.5.4 함수에 배열전달
• 전체 배열이 함수에 전달된다면, 조그만 변화라도
원래의 배열에 일어난다.
YES C 제 7 장 함수
75/96
예제 7.37 1차원 배열의 함수전달 프로그램을 작성하라.
#include <stdio.h>
int maximum( int [] );
/* 함수 원형*/
int maximum( int values[5] )
{
int max_value, i;
max_value = values[0];
for( i = 0; i < 5; ++i )
if( values[i] > max_value ) max_value = values[i];
return max_value;
}
void main(void)
{
int values[5], i, max;
printf("5개의 숫자를 입력하시오.\n");
for( i = 0; i < 5; ++i ) scanf("%d", &values[i] );
max = maximum( values );
printf("\n최대값은 %d이다.\n", max );
} YES C 제 7 장 함수
76/96
예제 7.38 배열의 요소의 크기를 같이 전달하는 프로그
램을 작성하라.
#include <stdio.h>
int findmaximum( int [], int ); /* 함수 원형 */
int findmaximum( int numbers[], int elements )
{
int largest_value, i;
largest_value = numbers[0];
for( i = 0; i < elements; ++i )
if( numbers[i] > largest_value )
largest_value = numbers[i];
return largest_value;
}
void main(void)
{
static int numb1[] = { 5, 34, 56, -12, 3, 19 };
static int numb2[] = { 1, -2, 34, 207, 93, -12 };
printf("numb1[]의 최대값은 %d이다.\n",
findmaximum(numb1, 6));
printf("numb2[]의 최대값은 %d이다.\n",
findmaximum(numb2, 6));
77/96
YES C 제 7 장 함수
}
예제 7.40 다차원 배열의 함수 전달 : 2차원 배열의 모든
요소를 더하는 함수를 C 프로그램으로 작성하라.
#include <stdio.h>
int add2darray( int [][5], int );
/* 함수 원형 */
int add2darray( int array[][5], int rows )
{
int total = 0, columns, row;
for( row = 0; row < rows; row++ )
for( columns = 0; columns < 5; columns++ )
total = total + array[row][columns];
return total;
}
void main(void)
{
int numbers[][5] = {{1,2,35,7,10},{6,7,4,1,0}};
int sum;
sum = add2darray( numbers, 2 );
printf("전체합은 %d이다.\n", sum );
}
78/96
YES C 제 7 장 함수
7.5.5 문자열의 인수전달
• C 언어에서의 문자열은 char 형의 1차원 배열로
표현하기 때문에 1차원 배열의 주소 전달 방식과
같다.
YES C 제 7 장 함수
79/96
예제 7.41 문자열을 함수로의 전달하는 프로그램을 작성
하라.
#include <stdio.h>
void strdsp1(char *pt);
void strdsp2(char str[]);
void main(void)
{
static char s1[] = "배열 형태의 문자열";
char *s2 = "포인터 형태의 문자열";
strdsp1(s1);
/* s1[]의 선두 주소를 전달 */
strdsp1(s2);
/* s2의 포인터 형태의 주소 */
}
void strdsp1(pt)
char *pt;
{
printf("%s\n", pt);
}
void strdsp2(str)
char str[];
{
printf("%s\n",
str);
YES C 제 7 장 함수
}
80/96
7.6 재귀함수
• C 언어의 함수가 자기 자신을 호출할 수 있는 재귀적 호출
의 특징을 가지고 있다. 이러한 함수를 재귀함수(recursive
function, 재귀호출 : recursive call)라 한다.
• 재귀 호출을 할 때 조건
– ① 함수 내에서 사용하는 변수는 자동 변수이어야 한다.
– ② 함수의 인수 전달 방식은 값에 의한 전달로 해야 한다.
• 재귀적 호출은 자기 자신을 호출하기 때문에 호출되어진 횟
수만큼 기억 장소가 배정되어야 하므로 스택 영역의
overflow를 주의해야 한다.
• 반복적으로 자기 자신을 호출하므로 순환을 멈출 수 있는
탈출 조건이 있어야 한다.
• 일반적으로 재귀적 호출을 수행하면 처리 속도가 늦고, 기
억 장소를 많이 사용하기 때문에 좋은 기법은 아니다.
• 일반적인 적용은 게임, 정렬 트리, 리스트들이다.
81/96
YES C 제 7 장 함수
예제 7.42 재귀함수를 이용하여 팩토리얼(factorial)을
계산하는 프로그램을 작성하라.
#include <stdio.h>
long factorial(long n);
void main(void)
{
long a;
a = factorial(7);
printf("7! = %1d\n", a);
}
long factorial(n)
long n;
{
if(n == 0)
return(1);
else
return(n*factorial(n-1));
} YES C 제 7 장 함수
82/96
예제 7.43 factorial을 재귀함수를 사용하여 계산하는 변형된 방
법.
•
•
#include <stdio.h>
long int factorial( long int );
•
•
•
•
•
•
•
•
•
long int factorial( long int n )
{
long int result;
if( n == 0l )
result = 1l;
else
result = n * factorial( n - 1l );
return ( result );
}
•
•
•
•
•
•
•
void main(void)
{
int j;
/* 함수 원형 */
for( j = 0; j < 11; ++j )
printf("%2d! = %ld\n", j, factorial( (long) j) );
}
YES C 제 7 장 함수
83/96
예제 7.44 하나의 문장을 입력받아 거꾸로 출력해 주는
재귀함수를 사용한 프로그램을 작성하라.
#include <stdio.h>
void print_back()
{
int ch;
if ((ch = getchar()) != '\n')
/*한글자를 입력받고 줄바꿈 문자인지 확인*/
print_back(); /* 줄바꿈 문자가 아닌 경우 되부름
putchar(ch);
/* 입력받은 문자 표시 */
}
*/
void main(void)
{
printf("Enter a line -> ");
print_back();
}
YES C 제 7 장 함수
84/96
예제 7.45 scanf()를 이용하여 사용자로부터 triangular 수를 입력하여 계산하는 프로그램을 작성하
라. triangular 수는 그 숫자 이전의 수를 모두 더하는 것이다. triangular 수가 7이라면 다음과 같다.
7 triangular = 7 + 6 + 5 + 4 + 3 + 2 + 1
•
•
#include <stdio.h>
long int triang_rec( long int ); /* 함수 원형 */
•
•
•
•
•
•
•
long int triang_rec( long int number )
{
long int result;
if( number == 0l )
result = 0l;
else
result = number + triang_rec( number - 1 );
return( result );
}
•
•
•
•
•
•
•
•
•
void main(void)
{
int request;
long int triang_rec(), answer;
printf("Enter number to be calculated. :");
scanf( "%d", &request);
answer = triang_rec( (long int) request );
printf("The triangular answer is %ld\n", answer);
}
YES C 제 7 장 함수
85/96
예제 7.46 피보나치(fibonacci) 수열을 재귀함수를 이용
하여 30항까지 구하는 프로그램을 작성하라.
#include <stdio.h>
int fib(int);
void main(void)
{
int x;
for(x=1; x<30; x++)
}
printf("%d\n", fib(x));
int fib(int num) /* Fibonacci 수를 구하는 재귀함수 */
{
switch(num) {
case 0: return(0);
break;
case 1: return(1);
break;
default: return(fib(num - 1) + fib(num - 2));
break;
}
86/96
} YES C 제 7 장 함수
예제 7.47 누승(累乘)을 계산하는 recursive 함수를 작성하라.
• #include <stdio.h>
• double power(double, unsigned);
• void main(void)
• {
•
printf("%lf \n", power(13.7, 5));
• }
• double power(double val, unsigned pow)
• {
•
if(pow == 0) /* pow(x, 0) returns 1 */
•
return(1.0);
•
else
•
return(power(val, pow - 1) * val);
• }
YES C 제 7 장 함수
87/96
7.7 main()함수와 매개변수
• C 언어에서 main() 함수도 하나의 함수로 취급하기
때문에 이를 호출하는 운영체제로부터 매개변수를 전
달받을 수 있다.
• 문법 : main() 함수의 일반적인 형식
int main(argc, argv)
int argc;
char *argv[];
{
. . . .
return();
}
– ① argc : 정수형으로 명령형 매개변수의 개수
– ② argv : 일차원 문자열 배열
YES C 제 7 장 함수
88/96
예제 7.48 main 함수에 매개변수를 포함하는 프로그램에서 매개
변수가 어떻게 저장되는지를 보여주는 프로그램을 작성하라.
#include <stdio.h>
void main(argc, argv)
int argc;
char *argv[];
{
int i;
printf("argc = %d\n", argc);
for (i=0; i<argc; ++i)
printf("argv[%d] = %s\n", i, argv[i]);
}
입력(DOS 창을 열고 실행함)
C:\Documents and Settings\Administrator\바탕 화면
\Debug>sr0748 test 100 200
실행결과
argc = 4
argv[0] = sr0748
argv[1] = test
argv[2] = 100
argv[3] = 200
YES C 제 7 장 함수
89/96
예제 7.49 프로그램 실행시 16진수를 받아들여 10진수로 변환한 후 출력하
는 프로그램. main()함수에서 매개변수로 16진수를 받아들인다.
•
•
#include <stdio.h>
#include <string.h>
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
void main(int argc, char* argv[])
{
int i, sqr=16*16*16, sum=0;
if (argc !=2 || strlen(argv[1]) !=4) {
printf("사용방법 : \n\t hex2dec 16진수 데이터 4자리\n");
return;
}
strupr(argv[1]);
for (i=0; i<4; i++) {
if (argv[1][i] >= 'A' && argv[1][i] <= 'F')
sum += ((argv[1][i] - 55)*sqr);
else if (argv[1][i] >= '0' && argv[1][i] <= '9')
sum += ((argv[1][i] - 48)*sqr);
else {
printf("사용방법 : \n\t test 16진수 데이터 4자리\n");
return;
}
sqr /= 16;
}
printf("16진수 %s의 10진수 값은 %d이다.\n", argv[1], sum);
}
입력(DOS 창을 열고 실행함)
프로그램명이 sr0749라 할 때
실행결과
16진수 1000의 10진수 값은 4096이다.
YES C 제 7 장 함수
90/96
•
•
예제 7.50 어떤 수의 약수를 구하는 프로그램을 main() 함수에서 매개변수
로 어떤 수를 받아들여 구하라.
#include <stdio.h>
#include <stdlib.h>
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
void main(argc, argv)
int argc;
char *argv[];
{
int x, i;
if ( argc !=2 ) {
printf("사용방법 : \n\t test 10진수\n");
return;
}
printf("input data : %s \n", argv[1]);
for(i=0; argv[1][i] != '\0'; i++)
if( argv[1][i] < '0' || argv[1][i] > '9') {
printf("사용방법 : \t test 10진수\n");
return;
}
x = atoi(argv[1]);
for(i=1; i<=x/2; i++)
if (x % i== 0)
printf("%d\n", i);
}
실행결과
Sr0750 123ab
Input data : 123ab
사용방법 :
test 10진수
•
•
Sr0750 342
Input data : 342
YES C 제 7 장 함수
91/96
예제 7.51 두 개의 10진 정수 m, n을 순서에 관계없이 입력하여
두 수 사이의 정수의 합을 구하는 프로그램을 main() 함수에서 매개변
수를 사용하여 작성하라.
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char *argv[])
{
int i, sum = 0, m, n;
if ( argc !=3 ) {
printf("사용방법 : \n\t test 10진정수 10진정수\n");
return;
}
for(i=0; argv[1][i] != '\0'; i++)
if( argv[1][i] < '0' || argv[1][i] > '9') {
printf("사용방법 : \n\t test 10진정수 10진정수\n");
return;
}
YES C 제 7 장 함수
92/96
예제 7.51 (계속)
for(i=0; argv[2][i] != '\0'; i++)
if( argv[2][i] < '0' || argv[2][i] > '9') {
printf("사용방법 : \n\t test 10진정수 10진정수\n");
return;
}
/* 문자열을 정수로 변환하는 함수 atoi 사용*/
m = atoi(argv[1]);
n = atoi(argv[2]);
/* 아래 if 문장은 XOR를 이용하여 두 수를 바꾸는 방법이다 */
if( m > n ) {
m ^= n;
n ^= m;
m ^= n;
}
for( i = m; i <= n; i ++)
sum += i;
printf(" %d ~ %d 사이의 합 = %d\n", m, n, sum);
}
YES C 제 7 장 함수
93/96
예제 7.52 세 개의 10진 정수 l, m, n을 main() 함수에서 매개변수를 사용하
여 입력하고, 예제 7.21에서 사용한 두 수의 gcm을 구하는 함수를 이용하여,
세 수의 최대공약수를 구하는 프로그램을 작성하라.
•
•
•
#include <stdio.h>
#include <stdlib.h>
int gcm(int, int); /* 함수 원형 */
•
•
•
•
•
•
•
void main(int argc, char *argv[])
{
int i, sum = 0, l, m, n;
if ( argc !=4 ) {
printf("사용방법 : \n\t test 10진정수 10진정수 10진정수\n");
return;
}
•
•
•
•
•
for(i=0; argv[1][i] != '\0'; i++)
if( argv[1][i] < '0' || argv[1][i] > '9') {
printf("사용방법 : \t test 10진정수 10진정수 10진정수\n");
return;
}
•
•
•
•
•
for(i=0; argv[2][i] != '\0'; i++)
if( argv[2][i] < '0' || argv[2][i] > '9') {
printf("사용방법 : \t test 10진정수 10진정수 10진정수\n");
return;
}
YES C 제 7 장 함수
94/96
예제 7.52 (계속)
for(i=0; argv[3][i] != '\0'; i++)
if( argv[3][i] < '0' || argv[3][i] > '9') {
printf("사용방법 : \t test 10진정수 10진정수 10진정수\n");
return;
}
•
•
•
•
•
•
•
•
•
•
•
•
}
•
•
•
•
•
•
•
•
•
•
•
•
/* 유클리드 호제법을 이용한 두 수의 최대공약수 구하는 함수 */
int gcm(int x, int y)
{
while(x != y)
if (x > y ) x -= y;
else y -= x;
return x;
}
입력(실행방법)
Sr0752 105 42 84
실행결과
105, 42, 84의 최대공약수 = 21
/* 문자열을 정수로 변환하는 함수 atoi 사용*/
l = atoi(argv[1]);
m = atoi(argv[2]);
n = atoi(argv[3]);
/* 세 수의 최대공약수 구하는 방법 : gcm(l, gcm(m, n)) */
printf(" %d, %d, %d의 최대공약수 = %d\n", l, m, n,gcm(l, gcm(m, n)));
YES C 제 7 장 함수
95/96
예제 7.53 실수를 main()함수의 매개변수로 받아들여, 정수부와
소수부로 나누어 출력하라.
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char *argv[])
{
int i, m;
double x, y;
if ( argc !=2 ) {
printf("사용방법 : \n\t test 실수데이터\n");
return;
}
for(i=0; argv[1][i] != '\0'; i++)
if((argv[1][i]<'0'||argv[1][i]>'9') && argv[1][i]!='.'){
printf("사용방법 : \n\t test 실수데이터\n");
return;
}
/* 문자열을 실수로 변환하는 함수 atof 사용 */
y = atof(argv[1]);
m = (int) y;
x = y - (float)m;
printf(" %f => 정수부 = %d, 실수부 = %f\n", y, m, x);
}
입력(실행방법)
Sr0753 123.52
실행결과
123.520000 => 정수부 = 123, 실수부 = 0.520000
YES C 제 7 장 함수
96/96