04강의-C언어

Download Report

Transcript 04강의-C언어

1
컴퓨터 개론 및 실습
강의 4
www.msharpmath.com
1
/ 23
2
함수 (Function)
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
www.msharpmath.com
2
/ 23
3
함수선언
■ 예제 : 밑변과 높이를 가진 사각형의 넓이를 구하는 함수
return type
declarer
function name
parameter_list
double area ( double a, double b ) { return
expression
a*b
; }
• 함수명 앞에 붙는 형 선언자와 동일한 데이터 형을 return 해야 한다.
• 함수의 연산결과를 나타내는 문장이 return 문이다.
• 함수의 모든 매개변수도 각각의 형을 선언해야 한다.
• return expr; 의 expr에 괄호 ()를 포함한 수식이 올 수 있다.
www.msharpmath.com
3
/ 23
4
가장 간단한 함수
■ 가장 간단한 함수
void dummy( ) { }
• 아무것도 리턴하지 않는 경우에는 데이터 형 대신에 void 를 쓴다
이때는 return ; 으로 아무것도 리턴하지 않는 명령어 return 만을 쓸 수 있다.
• 매개변수가 없으면 빈 소괄호 ( ) 를 쓴다
• 실행내용이 없으면 빈 중괄호 { } 를 쓴다
• 함수를 호출할 때 매개변수가 없을 때에도 빈 소괄호 ()를 써야 한다.
dummy() ;
www.msharpmath.com
4
/ 23
5
포맷된 출력 (formatted output)
■ 간단한 내장함수
int printf(const char *format, ... )
• format 은 데이터 형에 따라 여러가지가 있다
• 출력인수의 갯수에 따라 format 에서 데이터 형의 출력갯수도 같게 한다
• 수식값을 출력하는 간단한 함수로 몇 가지 사용예를 아래에서 살펴본다
c> printf(“%g”, 3+4) ;
7
c> a = 2; b = 3; printf(“ %g %g %g ”, a, b, a+b);
2 3 5
www.msharpmath.com
5
/ 23
6
다양한 포맷 (various format)
format이라는 문자열에는 두 가지 종류의 정보가 포함되는데, 그것은 보통
문자와 출력형식이다. 출력형식은 앞에 %가 붙은 문자로 표시해준다.
■ 변환 지정 문자
d, i 부호 있는 10진 정수 // %7d 는 7자리 정수로 출력
c
부호없는 정수형으로 변환된 문자
s
char * 문자열을 출력한다. ‘\0’을 만나거나 지정된 길이까지 출력하면 종료
f
부동소수 출력 // %6.2f 인 경우 pi를 소숫점아래 2자리인 총 6자리로 출력
//
e, E 과학기술 형식,
3.14
[-]mmm.ddde±xx
g, G 알맞은 형태로 선택한다(e, E, f 중에서)
n
변환하지 않고 출력
%
%로 출력
www.msharpmath.com
6
/ 23
7
다양한 포맷 (various format) •••
%와 문자 사이에는 다음과 같은 문자를 넣을 수도 있다. 상세한 내용은
교과서 p.361 을 참조한다.
■ 출력형식을 정리하는 기호
-
왼쪽 끝이 정렬된 출력
+
숫자 앞에 부호를 붙여준다(양의 부호를 포함)
space 첫 문자가 음의 부호 또는 빈칸이 된다
0
#
칸수에 맞게 앞에 0을 넣어 준다
0의 경우 첫 자리가 0이 되고, x나 X의 경우 0x 또는 0X가 앞에 붙게 된다.
e, E, f, g 와 G의 경우 소숫점이 항상 출력되며, g와 G의 경우 연속된 0을
없애지 않는다.
www.msharpmath.com
7
/ 23
8
call by value : 매개변수(parameter) 값 전달
■ 예제 : 밑변과 높이를 가진 사각형의 넓이
double area(double a, double b) { return a*b; }
▷ 위의 함수를 호출할 때
double a = 3.0, b = 4.0, S;
S = area( a ,b );
의 명령은 실제로
S = area( 3.0, 4.0 ); // a = 3.0; b = 4.0; 의 값만을 전달하며 a,b 와는 무관
와 동일하다. 이러한 이유는 a,b를 전달할 때 변수의 기억장소가 아니라 변수 a,b의
값을 보내기 때문이다. 다시 말해서, 위의 함수선언에서 매개변수는 “call by value”
로 전달한다.
www.msharpmath.com
8
/ 23
9
지역 변수 (local variable)
double area(double a, double b)
{
double s ;
s = a*b;
return s;
}
local variable, inside a block { } !!!
■ 지역변수(local variable)
함수의 내부에서만 사용되는 변수를 지역변수(local variable)라고 하며, 함수
바깥에서 정의된 변수와는 전혀 무관하다.
www.msharpmath.com
9
/ 23
10
블록 구조
#include <stdio.h>
int main(void)
{
int i = 3;
inside a block { }
{
int i = 5;
printf("inside i = %d \n", i);
}
printf("outside i = %d \n", i);
return 0;
}
inside i = 5
outside i = 3
■ 중괄호 쌍 { } 내부에서 정의하는 지역변수는 괄호 바깥에는 영향을 주지
않는다.
www.msharpmath.com
10
/ 23
11
외부 변수 (external variable)
#include <stdio.h>
main 함수의 바깥에 정의된 extern 변수
int common = 5;
int main(void)
{
extern int common;
extern 을 선언문 앞에 두어, 외부에서
정의된 변수를 사용할 것임을 알림
printf("common = %d \n", common);
return 0;
}
■ 외부 변수(external variable)
함수의 바깥에 선언한 변수를 외부변수라고 하며, 여러 함수에서 공통적으로
사용할 수 있다. 이때, 함수를 가지고 있는 파일에 extern 으로 선언하면
된다. 같은 파일 내에서는 extern을 생략해도 된다.
www.msharpmath.com
11
/ 23
12
정적 변수 (static variable)
■ 정적 변수(static variable)
변수선언 앞에 static을 붙여서 정적변수로 만들면 기억장소가 할당되고 함수의
호출이 끝나도 기억장소에는 마지막 값이 저장된다.
정적 변수로 선언하면 항상 기억장소가 할당되고
int showstatic(int n)
소멸되지 않는다.
{
static int show;
if( n == 0 ) printf("\n show = %d", show);
show = n*n;
return n;
}
첫 번째 호출에서 show 에는 25 가 기록
int main(void)
된다.
{
showstatic(5); // show = 25 now
showstatic(0); // show in memory is printed
return 0;
}
두 번째 호출에서는 show 에 이미 기록되
어 있던 25 의 값을 출력한다.
show 변수는 소멸되지 않고 기억장소에 값이 남아있다.
www.msharpmath.com
12
/ 23
13
call by value 의 특성
■ 예제 : 두 변수의 값을 바꾸는 함수
void swap(double a, double b)
{
double tmp;
tmp = a; a = b; b = tmp;
}
▷ 위의 함수를
x = 3; y = 4; swap(x,y);
으로 호출할 때 x, y 의 값은 바뀌지 않는다. 왜냐하면 매개변수를 call by value 로
전달하기 때문에 위의 명령은
x = 3; y = 4; swap(3,4);
을 호출한 것과 같다.
www.msharpmath.com
13
/ 23
14
초기화 (initialization)
■ 외부변수, 정적변수 : 특별한 초기값을 설정하지 않는 경우 0 으로 초기화된다.
■ 일반적인 변수: 초기화가 안되면 아무 값(garbage)이나 가지게 된다.
■ 단독 변수: 선언문에서 등호를 이용하여 초기화한다.
int n = 3 ;
double x = 3.14 , y = 2.718 ;
char c = ‘a’ ;
■ 배열 변수:
int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } ;
처럼 중괄호 { } 의 내부에 콤마로 분리된 값을 지정하는 형식으로 초기화된다.
크기를 생략하면 자동으로 크기가 지정된다. 위의 경우 크기는 12가 된다
■ 문자배열(문자열) : 특별한 배열로, 큰 따옴표를 이용하여 초기화한다.
char str[] = “special way to initialize” ;
www.msharpmath.com
14
/ 23
15
함수 prototype
#include <stdio.h>
함수 area 의 prototype
double area(double, double);
함수 area 를 호출하는 위치에
서, 어떤 내용인지는 아직 모르
int main(void)
지만 prototype으로부터 어떤
{
printf(“area = %g \n", area(3,4)); 형태임을 알기 때문에 사용가능
return 0;
}
double area(double a,double b) { return a*b; }
■ prototype
함수 area 의 content
함수의 내용은 없이 어떤 형태의 함수인가를 알려주는 것을 prototype이라고
한다. 위의 prototype에서는, area 라는 함수가 두 개의 double 형을
매개변수로 가지고, double 형의 수식값을 리턴한다는 것을 알려준다.
www.msharpmath.com
15
/ 23
16
header
■ header
• C언어에서 header는 filename.h 로 확장자 “.h” 로 끝나는 파일이다.
• 함수 prototype, 외부 변수 또는 extern 선언, 공통상수 등을 모아서
header에 넣어두면 프로그램 구조를 일목요연하게 파악할 수 있다.
• #include <stdio.h> 에서 stdio.h 는 표준 입출력 라이브러리에 대한 header 이다.
• C언어에서 제공하는 다양한 함수를 사용하려면 해당 header를 포함해야 한다.
예를 들어, 문자 c 가 숫자(0,1,2,3,4,5,6,7,8,9) 중의 하나인가를 판단하기 위해서
if( c >= ‘0’ && c <= ‘9’ )
대신에
#include <ctype.h>
인 header 를 포함시키면
if( isdigit(c) )
와 같이 함수 isdigit 를 사용할 수 있다.
www.msharpmath.com
16
/ 23
17
되부름 (recursion)
■ recursion
• 함수를 정의하면서 자기자신을 다시 호출하는 함수를 되부름함수라고 한다.
예를 들어, 자연수 n의 계승(factorial)의 정의
n ! = n x (n-1)!
에 따라 함수 factorial을 다음과 같이 작성하면
int factorial(int n)
{
if ( n == 1 ) return 1;
return n * factorial(n-1);
}
함수 factorial은 자신을 정의하는 내용에서 다시 자신을 호출하는 구조가 된다.
• 되부름 함수는 반드시 하나 이상의 탈출구(즉, 자신을 부르지 않는 경우)를
가져야만 한다.
www.msharpmath.com
17
/ 23
18
C 프리프로세서 (preprocessor)
■ C는 프리프로세서(preprocessor)에 의해 일종의 언어 확장기능을 제공한다.
■ #include 명령에 의해 컴파일 시 어떤 파일을 실어 올 수 있다.
#include “filename”
또는
#include <filename>
■ #define 명령으로 긴 문자열을 하나의 심벌로 대치하여 사용할 수 있다.
www.msharpmath.com
18
/ 23
19
#define 명령에 의한 상수
■ #define 에 의한 상수 선언
• 세미콜론 (;) 을 갖지 않는 문장이다
• #define으로 선언된 상수는 컴파일될 때, 선언된 상수로 치환된다.
예를 들어, 아래의 명령
#define PI 3.14159
double a ;
a = PI * PI ;
// 세미콜론이 없다
은 컴파일하기 전에
double a ;
a = 3.14159 * 3.14159 ;
으로 치환이 일어난다. 그리고 상수이므로 쓰기가 금지된다(예, PI = 3)
www.msharpmath.com
19
/ 23
20
macro 치환 (1)
■ #define name string
• 상수를 선언할 때 사용한 #define 을 macro 치환에도 사용할 수 있다.
• 매크로 치환은 동일한 이름에만 적용된다. YES 가 정의될 때, YESDO 에서는
치환이 일어나지 않는다. 따옴표 내부에서는 “YES” 처럼 같은 이름이라도 치환이
일어나지 않는다.
• 매크로 선언시 string 에서는 괄호를 이용하는 것이 좋다
#define square(x)
x*x
는 square(a+b) 가 a+b*a+b 로 치환되므로 원하는 결과와는 다르게 된다. 따라서
#define square(x)
( (x)*(x) )
으로 사용해야 한다.
www.msharpmath.com
20
/ 23
21
macro 치환 (2)
■ #define name string
• 매크로 인수는 여러 번 사용될 수 있으므로 ++i 같은 증가/감소연산자는
사용하지 않도록 한다.
#define max(A,B) ( (A)>(B) ? (A) : (B) )
인 경우 max(i++,j++) 는 두 번의 증가를 가져오므로 좋지 않은 사용예이다.
• 매크로 치환은 같은 이름에 다시 정의될 수 있고, 정의는 이전의 정의를 다시
재사용할 수 있다.
■ #undef name
• 매크로 치환은 #undef 에 의해서 해제될 수 있다.
www.msharpmath.com
21
/ 23
22
macro 치환 (3)
■ 따옴표 속에 있는 변수나 상수를 치환하는 경우
• #을 사용한다. 예를 들어
#define dprint(expr)
printf(#expr “ = %g \n”, expr)
인 매크로 치환을 사용하면 다음과 같은 효과를 얻는다.
dprint(x/y);
 printf(“x/y” “ = %g \n”, x/y );  printf(“x/y = %g \n”, x/y );
■ ## 연산자
#define paste(front, back) front ## back
을 이용하면 paste(name,1) 은 name1 이라는 변수를 만들어낸다.
www.msharpmath.com
22
/ 23
23
조건부 포함
■ #if
#else
#endif
#ifdef
#ifndef
• 컴파일 시의 조건에 따라 포함할 지 포함하지 않을지를 선택할 수 있다.
예를 들어, hdr.h 라는 헤더파일을 단 한 번만 포함하고 싶다면 다음을 포함한다.
#ifndef HDR
#define HDR
/* contents of hdr.h go here */
#endif
일단 hdr.h 파일이 포함되면 HDR 라는 이름이 정의된다. 다음에 또 같은 파일을
포함하면, 이름이 이미 정의되었으므로 #endif 로 뛰게 된다.
www.msharpmath.com
23
/ 23