Transcript include

C 개론 정리
Standard I/O
표준 입출력 함수(1)
• C 표준 라이브러리에서 제공
• 키보드 입력, 화면 출력
• <stdio.h>에서 정의
• 표준 입출력 함수를 사용하기 위해서는 반드시 이 파일을
incldue 시켜야 한다.
함수명
입력
int scanf(“형식지정 문자열”, &parameter list);
출력
int printf(“형식지정 문자열”, parameter list);
3
표준 입출력 함수(2)
/* 예제 1.7 */
#include <stdio.h>
void main(void)
{
char ch;
printf(“한 개의 문자를 입력하시오\n”);
scanf(“%c”, &ch);
printf(“입력한 값은 =%c\n”, ch);
}
4
표준 입출력 함수(3)
• 변환 문자
문자
설명
%d
10진수 정수
%o
부호없는 8진수 정수
%x
부호없는 16진수 정수
%u
부호없는 10진수 정수
%lu
부호없는 10진수 long형 정수
%ld
10진수 long형 정수
%c
문자 상수
%s
문자열
%f
실수형
%e
지수형
5
표준 입출력 함수(4)
/* 예제 2.2 */
#include <stdio.h>
void main(void)
{
float f=123.4567;
printf("%8.3f\n", f);
printf("%-8.3f\n", f);
printf("%15.3f\n", f);
printf("%8.0f\n", f);
}
6
표준 입출력 함수(5)
• 특수 문자
문자
\n
설명
커서를 한 라인 아래의 첫 번째 열로 이동
\t
탭(tab)의 크기만큼 커서를 이동
\r
커서를 현재 라인의 첫 번째로 열로 이동
\“
“를 출력
\‘
‘를 출력
\\
\를 출력
\b
커서를 한 컬럼 뒤로 이동(back space)
\a
벨소리 발생
\0
NULL
7
표준 입출력 함수(6)
/* 예제 2.3 */
#include <stdio.h>
void main(void)
{
int a;
a=67;
printf("%C 언어\n", a);
}
8
Variables & Data Type
메모리
0과 1의 비트 값을 저장할 수 있는 저장공간
Ex) PC133 256MB SDRAM
0 0 1
1 1 0 0 0 0 1 1 0 1 0 0 1
1 0 0
256×1024×1024×8 = 21,4748,3648 bits
!
한번에 사용하기에는 너무 큰 용량이므로 적당히 나누어 사용해야 함
10
변수(1)
• 메모리에 값을 저장하고 꺼내기 위한 장소를 의미
• 사용하기 전에 반드시 선언
• 컴파일러에게 어떤 변수형이 사용되는가를 알려줌
char man = 26;
0 0 1
1 1 0 0 0 0 1 1 0 1 0 0 1
1 0 0
man
11
변수(2)
• 변수명 규칙
•
•
•
•
•
•
•
대문자, 소문자, 숫자, 밑줄(_)을 사용
가급적 의미 부여
첫 글자는 반드시 영문자 또는 밑줄(_)로 시작
대,소문자 구별
32문자 길이
예약어는 사용 불가
<표 1.1> 헝가리언 표기법 참고
12
변수(3)
• 변수 선언 형식
data-type
• 예) int
float
variabele-name1, variable-name2,,, ;
counter;
x,y,z;
• 치환(assignment)
• 선언된 변수에 값을 저장하는 것
variable-name = value;
• 예) counter = 100;
13
자료형(1)
• 기본 자료형
자료형
문자 데이터
크기
8bit
키워드
char
부호 있는 정수
16bit(?) 32bit
int
실수
32bit
float
배정도 실수
64bit
double
값이 없음
0
void
14
자료형(2)
/* 자료형 크기 */
void main()
{
char
int
float
double
c;
i;
f;
d;
printf("size
printf("size
printf("size
printf("size
}
of
of
of
of
integer type variable is %d\n", sizeof(i));
character type variable is %d\n", sizeof(c));
float type variable is %d\n", sizeof(f));
double type variable is %d\n", sizeof(d));
15
자료형(3)
/* 예제 3.2 */
#include <stdio.h>
void main()
{
char ch1, ch2;
ch1=‘A’, ch2=‘B’;
printf(“%c, %d, %x\n”, ch1, ch1, ch1);
printf(“%c, %d, %x\n”, ch2, ch2, ch2);
}
16
자료형(3)
• 자료형 수정자
•
•
•
•
signed
unsigned
long
short
char
unsigned char
int
long int
17
자료형(4)
• ANSI C
자료형
자료형
크기(bit)
최소범위
char
8
-128~127
unsigned char
8
0~255
signed char
8
-128~127
int
16/32
-32,768~32,767
unsigned int
16/32
0~65,536
signed int
16/32
-32,768~32,767
short int
16
-32,768~32,767
unsigned short int
16
0~65,536
signed short int
16
0~65,536
long int
32
-2,147,483,648~ 2,147,483,647
signed long int
32
-2,147,483,648~ 2,147,483,647
unsigned long int
32
0~4,294,967,295
float
32
3.4x10-38~3.4x10+38
double
64
1.7x10-308~1.7x10+308
long double
80
3.4x10-4932~3.4x10+4932
18
자료형(5)
• 오버플로우(overflow)
• 프로그램 수행 시, 데이터 값이 변수의 자료형이 허용하는 범위
를 넘으면 발생
• 충분한 범위를 허용하는 자료형으로 선언해야 함
• 그러나, 무작정 큰 범위의 자료형을 사용하는것 메모리 낭비
를 초래
예) short int number = 40960;
예) long int number = 40960;
19
자료형(6)
/* overflow */
#include <stdio.h>
void main()
{
short int i = 32767;
printf("%hd %hd %hd\n", i, i+1, i+2);
}
20
자료형(7)
• 열거형 상수
enum tag { enum-list }
• 예) enum weekend{mon,tue,wed,thu,fri,sat,sun};
예) enum weekend{mon=5,tue,wed,thu,fri,sat,sun};
예) enum boolean{NO,YES};
• #define 문
#define
macro
• 예) #define
value
PI
3.14195
21
자료형(8)
• typedef
• 자료형 재정의
typedef
기존 자료형
• 예) typedef
int
새로운 자료형;
integer;
22
자료형(9)
/* 예제 3.5 */
#include <stdio.h>
typedef
int
integer;
void main(void)
{
integer i,j;
i=5, j=6
printf(“%d는 %d보다 크다\n”,i, j);
printf(“%d는 %d보다 크다\n”,j, i);
}
23
ASCII문자와 진수(1)
• 진수의 종류
종류
설명
예
10진수
0~9까지의 숫자를 이용
123
8진수
0~7까지의 숫자를 이용
034
16진수
0~9,A~F(a~f)를 이용
0x23
24
ASCII문자와 진수(2)
/* 예제 3.6 */
#include <stdio.h>
void main(void)
{
int i;
printf(“8진수를 입력하시오\n”);
scanf(“%o”, &i);
printf(“입력 코드에 해당하는 문자 %c\n”, i);
}
25
ASCII문자와 진수(3)
/* 예제 3.7 */
#include <stdio.h>
void main(void)
{
int i;
printf(“16진수를 입력하시오\n”);
scanf(“%x”, &i);
printf(“입력 코드에 해당하는 문자 %c\n”, i);
}
26
ASCII문자와 진수(4)
/* 예제 3.8 */
#include <stdio.h>
void main(void)
{
int i=555;
printf(“10진수 %d\n”, i);
printf(“8진수 %o\n”, i);
printf(“16진수 %x\n”, i);
}
27
제어문
프로그램의 구조
• 순차적 구조
• 처음부터 순서대로 실행함
• { }안의 일반적인 문장들
• 선택 구조
• 조건에 따라 대응되는 값으로 분기되어 실행함
• if, if~else, switch
• 반복 구조
• 어떤 조건이 만족 될 때까지 일정한 명령 또는 문장들을 반복하여 실행
함
• for, while, do while
29
if 문
• 일반 형식
if (condition)
{
statement1;
statement2;
.....;
}
if (봄이_오면)
{
꽃이_핀다();
}
if (봄이_오면)
{
if(온도>0도)
꽃이_핀다();
}
30
/* 예제 5.1 */
#include <stdio.h>
void main()
{
int a,b,k;
printf("두개의 정수를 입력하세요.\n");
scanf("%d %d", &a, &b);
if(a>b){
k=a-b;
printf("%d가 %d보다 %d 만큼 크다.\n", a, b, k);
}
if(a<b){
k=b-a;
printf("%d가 %d보다 %d 만큼 크다.\n", b, a, k);
}
if(a==b){
printf("두 정수는 같다.\n");
}
}
31
if ~ else 문
• 일반 형식
if (condition)
{
statement1;
statement2;
.....;
}
else
{
statement3;
statement4;
.....;
}
32
/* 예제 5.2 */
#include <stdio.h>
void main()
{
int hak;
printf("성적을 입력하세요.\n");
scanf("%d", &hak);
if(hak>=60)
printf("Pass\n");
else
printf("Drop\n");
}
33
switch 문
• 일반 형식
switch (condition-variable)
{
case constant1:
statement1;
.....;
break;
case constant2:
statement2;
.....;
break;
.....
default:
statementn;
break;
}
/* omittable */
34
/* 예제 5.3 */
#include <stdio.h>
void main()
{
int i, j;
char opt;
printf("정수, 연산자(+,-,*,/), 정수를 입력하시오.\n");
scanf("%d %c %d", &i, &opt, &j);
switch(opt)
{
case ‘+’:
printf("%d %c %d = %d\n", i, opt, j, i+j);
break;
case ‘-’:
printf("%d %c %d = %d\n", i, opt, j, i-j);
break;
case ‘*’:
printf("%d %c %d = %d\n", i, opt, j, i*j);
break;
case ‘/’:
printf("%d %c %d = %d\n", i, opt, j, i/j);
break;
}
}
35
/* break statement */
#include <stdio.h>
void main()
{
char ch;
printf("영문자 하나를 입력하세요.\n");
scanf("%c",&ch);
switch(ch)
{
case ‘a’:
printf("Now is ");
case ‘b’:
printf("the time ");
case ‘c’:
printf("for all good men\n");
break;
case ‘d’:
printf("The summer ");
case ‘e’:
printf("soldier \n");
}
}
36
for 문
• 일반 형식
for (초기값①;조건식②;증감식③)
{
statement1;
.....;
}
statement3;
.....;
• 무한 루프(infinite-loop)
for (;;)
{
.....;
}
37
/* 예제 5.4 */
#include <stdio.h>
void main()
{
int i, sum=0;
for(i=1; i<=10; i++)
{
sum = sum + i;
}
printf(“1부터 10까지의 합 = %d\n”, sum);
}
38
/* 에제 5.6 */
#include <stdio.h>
int labs(int i);
/* 사용자 정의 함수 */
void main()
{
int minus, plus, i, result;
printf(“음의 정수를 입력하시오.\n”);
scanf(“%d”, &minus);
printf(“양의 정수를 입력하시오.\n”);
scanf(“%d”, &plus);
for(i=minus;i=<=plus;i++){
result = labs(i);
printf(“labs(%2d) = %2d\n”, i, result);
}
}
int labs(int i)
{
if(i>=0)
return i;
else
return –i;
}
39
/* 예제 5.6 */
#include <stdio.h>
int factorial(int j);
void main()
{
int i;
long result;
for(i=1;i<=10;i++) {
result = factorial(i);
printf(“%4d!=%10ld\n”, i, result);
}
}
long factorial(int j)
{
int i;
long result = 1;
for(i=1;i<=j;i++)
result *= i;
return result;
}
40
/* 재귀함수를 이용한 factorial */
#include <stdio.h>
long factorial(int j);
void main()
{
int j;
long result;
printf("정수를 입력하세요.\n");
scanf("%d", &j);
result = factorial(j);
printf("%d! = %ld\n", j, result);
}
long factorial(int j)
{
long result=1;
if (j > 1) {
result = j*factorial(j-1);
return result;
} else
return j;
}
41
/* 예제 5.10 */
#include <stdio.h>
void main()
{
int a, b;
for(a=1;a<10;a++) {
for(b=1;b<10;b++) {
printf(“%3d”, a*b);
if(b==9)
printf(“\n”);
}
}
}
42
while 문
• 일반 형식
while(condition)
{
statement1;
.....;
}
statement1;
43
/* 예제 5.11 */
#include <stdio.h>
void main()
{
int i=1, sum=0;
while (i<=10){
sum = sum + i;
i++;
}
/* i값 초기화 */
/* 조건 */
/* i값 증가 */
printf(“1부터 10까지의 합 = %d\n”, sum);
}
44
do while 문
• 일반 형식
do {
statement1;
.....;
} while(condition);
/* caution */
statement2;
45
/* 예제 5.11을 do while로 작성 */
#include <stdio.h>
void main()
{
int i=0, sum=0;
do {
i++;
sum = sum + i;
} while (i<10);
/* i값 초기화 */
/* i값 증가 */
/* 조건 */
printf(“1부터 10까지의 합 = %d\n”, sum);
}
46
직접 하기!(1)
• 키보드로부터 정수 하나를 입력 받아서 그 값이 홀수
인지 짝수인지를 알려 주는 프로그램을 작성하시오.
47
직접 하기!(2)
• 키보드로부터 영문자 하나를 입력받아 자음인지 모음
인지를 구별하여 화면에 출력하는 프로그램을 작성
하시오.
48
직접 하기!(3)
• 1+1/2+1/3+...+1/10을 구하는 프로그램을 작성하시오.
• 1+1/2+1/3+...+1/n이 5를 넘는 최초의 n의 값을 구하
는 프로그램을 작성하시오.
49
함수(1)
구조적 프로그래밍(1)
• Divide & Conquer
• 하나의 커다란 작업을 기능적으로 여러 개의 작은 부분으로 나
누어 해결하는 기법
• 문제의 각개 격파
• 모듈(module)
• 특정 작업을 수행하는 하나의 작은 Sub-Program
• C 언어에서는 일반적으로 모듈을 함수 형태로 표현
51
구조적 프로그래밍(2)
• 모듈라(modular) 프로그래밍
• 하나의 프로그램은 관련된 부분(모듈)들로 구성
• 예) 성적 처리 프로그램
과목의 점수를
입력 받는 모듈(함수)
과목의 평균을
내는 모듈(함수)
계산된 과목의
평균을 출력하는
모듈(함수)
Module 2
Module 3
Module 1
Module 1
Module 2
Module 4
Module 3
Module 5
Module 6
구조적으로 잘 설계
된 프로그램은 마치
LEGO 블록을 쌓는
것과 유사하다.
52
구조적 프로그래밍(3)
• 함수(function)
• 입력 받은 데이터에 대하여 완성된 특정 결과를 발생시키는 일
종의 black box
• 외부로부터 함수로의 인터페이스는 입력과 출력
• 함수 안의 구체적인 내용은 캡슐화되어 숨겨짐
• 예) 곱셈 함수
first
second
number number
z = f(x,y)
x : first number
y : second number
z : result
A*B
f(x,y)
result
53
구조적 프로그래밍(4)
• 함수의 종류
• 내장 함수
• C 컴파일러와 함께 기본적으로 제공되는 함수들
• 표준 라이브러리(library)
• 사용자 정의 함수
• 사용자가 필요에 따라서 자신의 프로그램에 맞게 작성하는 함수들
• main() 함수
• 프로그램이 실행되면 가장 먼저 실행되는 함수
• 다른 함수들의 실행순서를 결정해 주는 함수
• 모든 C 프로그램은 반드시 하나의 main() 함수를 갖는다.
54
구조적 프로그래밍(5)
• main() 함수의 예
• 급여 계산 프로그램
•
•
•
•
gross_pay() : 총급여를 계산하는 함수
taxes() : 세금을 계산하는 함수
net_pay() : 총 급여에서 세금을 제외한 급여 계산 함수
output() : 결과를 출력하는 함수
프로그램이 실행되면,
어떠한 순서로 함수가
실행될 것인가?
55
구조적 프로그래밍(6)
• main()함수의 예
main()
You go first
I’m done
gross_pay( )
You go second
I’m done
taxes( )
You go third
I’m done
net_pay( )
You go last
I’m done
output( )
The main() Function Controls All Other Functions
56
C 프로그램의 구조(1)
• 하나 이상의 함수로 구성
• 이중 반드시 하나의 main() 함수가 있어야 한다.
• 함수의 머리(header)와 본체(body)로 구성
• Header : 전처리 기에 대한 문장과 함수 (예:#include)
• 함수의 이름
• 함수에 입력되는 값의 데이터형(있을 경우)
• 함수가 반환하는 값의 데이터형(있을 경우)
• Body : 중괄호({})로 싸여 블록화
57
C 프로그램의 구조(2)
#include <stdio.h>
C 프로그램
int main( )
헤더(header) : #include
{
…중략…
sum( );
main() 함수
printf(“Hello World”);
…중략…
그 밖의 함수
}
int sum(void)
{
…중략…
}
58
함수의 원형과 정의(1)
• 함수를 사용하기 위해 함수의 원형을 선언
• 소스 파일 내에서 선언
• 별도의 헤더 파일(*.h)에 선언
• #include <파일명.h>
• 원형(prototype)을 사용 함으로서 에러를 방지하고 가독
성을 높임
• 컴파일러에게 함수의 반환형 및 매개변수 정보를 전달
type function-name(type parameter1,
type parameter2,
type parametern);
59
/* 함수 사용 1 */
#include <stdio.h>
int max(int a, int b);
void main(void)
{
...;
max(1,5);
//function call
...;
}
int max(int a, int b);
{
if(a>=b)
return a;
else
return b;
}
/* 함수 사용 2 */
#include <stdio.h>
int max(int a, int b);
{
if(a>=b)
return a;
else
return b;
}
void main(void)
{
...;
max(1,5);
//function call
...;
}
60
#include <stdio.h>
/* 과거의 선언 방법 */
int sum();
#include <stdio.h>
/* 완전한 원형 */
int sum(int s1, int s2, int s3);
void main()
{
int vol;
void main()
{
int vol;
vol = sum(12, 5, 9, 7);
printf("Volume: %d\n", vol);
vol = sum(12, 5, 9, 7);
printf("Volume: %d\n", vol);
}
}
int sum(int s1, int s2, int s3)
{
return s1+s2+s3;
}
int sum(int s1, int s2, int s3)
{
return s1+s2+s3;
}
61
함수의 원형과 정의(2)
• 가변길이 매개변수 리스트
• 매개변수의 수가 변하는 함수
printf(“The C programming.”);
printf(“The %s programming.”, str);
• 가변길이 매개변수를 사용하는 함수의 원형
int myfunction(int a, ...);
62
return 문
• 함수를 호출 한 쪽으로 결과를 반환
• return문을 사용하여 값을 반환
return ret-value;
• 함수 수행의 흐름을 변경
• return을 만난 함수는 즉각 복귀
• 함수 수행 도중에 함수의 종료가 가능
return;
63
/* 예제 6.1 */
#include <stdio.h>
int A(int a);
void B(int a);
void main()
{
int i, res;
for(i=0; i<=5; i++)
{
res = A(i);
printf(“i의 값은 %d\n”, res);
}
for(i=0; i<=5; i++)
{
B(i);
}
}
64
int A(int a)
{
return(a=a*2);
}
int B(int a)
{
if(a<3)
return;
else
printf(“a의 값 = %d\n”, a);
}
65
사용자 정의 함수의 종류(1)
• 매개변수도 없고 리턴 타입도 없는 경우
• 함수를 호출 할 때 매개변수(파라메터, 인수)가 없음
• 함수의 실행 결과를 되돌려 주지 않음
void A(void)
{
……
}
B()
{
……
}
66
#include <stdio.h> /* 예제 6.2 */
void A(void);
void B(void);
void main(void)
{
A();
B();
printf(“ main() 함수 내에서의 문자 출력\n”);
}
void A(void)
{
printf(“ A() 함수 내에서의 문자 출력\n”);
}
void B(void)
{
printf(“ A() 함수 내에서의 문자 출력\n”);
}
67
사용자 정의 함수의 종류(2)
• 매개변수는 있고 리턴 타입은 없는 경우
• 함수를 호출 할 때 매개변수(파라메터, 인수)가 있음
• 함수의 실행 결과를 되돌려 주지 않음
void upper_case(char ch);
68
#include <stdio.h> /* 예제 6.3 */
void upper_case(char ch);
void main(void)
{
char ch1;
while((ch1=getchar()) != EOF)
{
upper_case(ch1);
}
}
void upper_case(char ch)
{
char res;
if (ch >= ‘a’ && ch <= ‘z’)
res = ch – 32;
else
res = ch;
putchar(res);
}
69
사용자 정의 함수의 종류(3)
• 매개변수는 없고 리턴 타입은 있는 경우
• 함수를 호출 할 때 매개변수(파라메터, 인수)가 없음
• 함수의 실행 결과를 되돌려 줌
int sum_a(void);
70
#include <stdio.h> /* 예제 6.4 */
#define M 5
int sum_a(void);
void main(void)
{
int result;
result = sum_a();
printf(“배열 원소의 합계 = %d\n”, result);
}
int sum_a(void)
{
int a[M] = {11, 33, 44, 222, 55};
int i, sum=0;
for (i=0; i<M; i++)
sum += a[i];
return sum;
}
71
사용자 정의 함수의 종류(4)
• 매개변수도 있고 리턴 타입도 있는 경우
• 함수를 호출 할 때 매개변수(파라메터, 인수)가 있음
• 함수의 실행 결과를 되돌려 줌
int input_round(fload a);
72
#include <stdio.h> /* 예제 6.5 */
int input_round(float a);
void main(void)
{
float f=1.3;
int i;
for(i=0; i<=10; i++)
printf(“%f의 round는 %d\n”, f*i, input_round(f*i));
}
int input_round(float a)
{
a = a + 0.5;
return (int)a;
}
73
함수(2)
매개 변수의 전달 방식
• 두 가지로 구분!
• 값이 그대로 복사되는 값에 의한 호출 방법
• 원래의 변수의 값은 변하지 않음!
• 일반 적인 방법
• 변수의 주소 값이 전달되는 참조에 의한 호출 방법
• 원래의 변수의 값을 변경 할 수 있음
• 특수한 경우!
75
매개 변수
• 매개 변수 전달 방법
• 값에 의한 호출
• 인수의 값(value)이 함수의 형식 매개 변수에 복사
• 함수의 매개 변수에서 일어나는 변화가 인수에 영향을 미치지 않음
• call by value
• 참조에 의한 호출
• 인수의 주소(reference)가 함수의 형식 매개변수에 복사
• 매개변수에서 일어나는 변화가 인수에 영향을 미침
• call by reference
76
/* call by value */
#include <stdio.h>
void swap(int num1, int num2);
/* call by reference */
#include <stdio.h>
void swap(int *num1, int *num2);
void main(void)
{
int num1 = 100;
int num2 = 500;
swap(num1, num2);
printf(“%d, %d”, num1, num2);
}
void main(void)
{
int num1 = 100;
int num2 = 500;
swap(&num1, &num2);
printf(“%d, %d”, num1, num2);
}
void swap(int num1, int num2);
{
int temp;
void swap(int *num1, int *num2);
{
int temp;
temp = num1;
num1 = num2;
num2 = temp;
printf(“%d, %d”, num1, num2);
}
temp = *num1;
*num1 = *num2;
*num2 = temp;
printf(“%d, %d”, num1, num2);
}
77
Call by Value(1)
int num1, int num2;
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
num1
num2
num1 = 100; num2 = 500;
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
100
500
78
Call by Value(2)
swap()함수에 의해 새로운 int num1, int num2 생성
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
100
500
swap(num1, num2);
num1
num2
/* 값이 복사 */
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
100
500
100
500
79
Call by Value(3)
swap()함수에서 num1, num2 교환 후의 상태
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
100
500
500
100
main()에 있는 num1, num2의 값은 교환되지 않음
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
100
500
500
100
80
Call by Reference(1)
int num1, int num2;
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
num1
num2
num1 = 100; num2 = 500;
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
100
500
81
Call by Reference(2)
swap()함수에 의해 새로운 int *num1, int *num2 생성
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
100
500
swap(&num1, &num2);
num1
num2
/* 주소가 복사 */
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
100
500
10
14
82
Call by Reference(3)
swap()함수에서 *num1, *num2 교환 후의 상태
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
100
500
10
14
main()에 있는 num1, num2의 값이 교환됨
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
500
100
10
14
83
재귀 함수
• 자기 자신을 다시 호출하는 함수
• 순환(recursion) 함수
• 매개 변수와 지역적인 데이터를 스택(stack)에 저장
• 함수가 순환적으로 호출될 때, 그 함수는 새로운 매개 변수와 지역
변수를 가지고 실행
• 함수를 구성하는 실행 명령 부분은 오직 하나만 존재
• 함수 내에서 하나의 조건문이 필요
• 순환의 진행 여부를 판단
• 일반적으로 자주 사용되지는 않으나 특정 알고리즘을 단순화 시
키는데 매우 유용
84
/* 재귀 함수 1*/
#include <stdio.h>
void recurse(int i);
void main()
{
recurse(0);
}
void recurse(int i)
{
if(i<10) {
recurse(i+1);
printf(“%d”, i);
}
}
/* recursive call */
85
/* 재귀 함수 2*/
#include <stdio.h>
void rcopy(char *s1, char *s2);
void main()
{
char str[80];
rcopy(str, “The C Programming Language”);
printf(str);
}
void rcopy(char *s1, char *s2)
{
if(*s2) {
/* NOT END OF STRING */
*s1++ = *s2++;
rcopy(s1, s2);
} else
*s1 = ‘\0’;
}
86
/* 재귀 함수 3*/
#include <stdio.h>
void f1(int a);
void f2(int b);
void main() {
f1(30);
}
void f1(int a) {
if(a) f2(a-1);
printf(“%3d”, a);
}
void f2(int b) {
printf(“.”);
if(b) f1(b-1);
}
87
/* 재귀 함수 4*/
#include <stdio.h>
int factorial(int i)
void main()
{
int num;
scanf(“%d”, &num);
printf(“%d factorial is %d\n”, num, factorial(num));
}
int factorial(int i)
{
if(i == 1) return 1;
else return i * factorial(i-1);
}
88
/* 예제 6.7 */
#include <stdio.h>
void swap_a(int m, int n);
void swap_b(int *m, int *n)
void main(void)
{
int i=2, j=3;
printf(“i와 j의 초기값 = %d %d\n”, i, j);
swap_a(i, j);
printf(“swap_a() 함수 호출 후의 i, j의 값 = %d %d\n”, i, j);
swap_b(&i, &j);
printf(“swap_b() 함수 호출 후의 i, j의 값 = %d %d\n”, i, j);
}
// 다음 페이지 계속
89
void swap_a(int m, int n)
{
int temp;
temp = m;
m = n;
n = temp;
}
void swap_b(int *m, int *n)
{
int temp;
temp = *m;
*m = *n;
*n = temp;
}
90
/* 예제 6.8 */
#include <stdio.h>
int sum(int a);
void main(void)
{
int input, s=0;
printf(“양의 정수를 입력하시오\n”);
scanf(“%d”, &input);
s=sum(input);
printf(“1부터 %d까지의 합 = %d\n”, input, s);
}
int sum(int a)
{
if(a<=1) return 1;
else return (a+sum(a-1));
}
91
/* 예제 6.12 */
#include <stdio.h>
#include <stdlib.h>
void main(void)
{
int sum, a, b, c, d, e;
srand(100);
a = rand();
b = rand();
c = rand();
d = rand();
e = rand();
sum = a + b + c + d + e;
printf(“난수 %d, %d, %d, %d, %d의 합 = %d\n”, a, b, c, d, e,
sum);
}
92
/* 예제 6.16 */
#include <stdio.h>
int max(int a, int b, int c);
void main(void)
{
int r = max(13, 14, 15);
printf(“최대값=%d\n”, r);
}
int max(int a, int b, int c)
{
int r;
if(a>=b && a>=c) r = a;
else if(b>=a && b>=c) r = b;
else r = c;
return r;
}
93
기억부류
변수의 종류
• 자료의 형태에 따른 분류
• int, float, double, char …
• 기억 부류(변수에 저장되는 값이 프로그램에 미치는
범위)에 따른 분류
• 자동 변수, 외부 변수, 전역 변수, 정적 변수, 레지스터 변수
95
기억 부류
• 변수에 저장되어 있는 값의 유효 범위(scope)
• 값이 얼마동안 기억장소에 기억되어 있는 가를 결정
• 변수의 선언 위치 및 사용되는 수정자에 따라 결정
• 선언 위치에 따른 종류
• 지역변수(local)
• 전역변수(global)
• 수정자에 따른 종류
•
•
•
•
자동변수(auto)
외부변수(extern)
정적변수(static)
레지스터(register)
96
변수의 선언 위치(1)
• 지역(local) 변수
• 함수 내부에 선언
• 반드시 블럭의 시작부분에서 선언
• 함수 내부에서만 참조
• 다른 함수에서 동일한 변수 이름 사용 가능
• 임시적(temporary)
• 변수가 선언된 함수가 실행 될 때만 유효
• 함수가 끝나면 기억장소에서 소멸
• 함수의 매개변수도 지역변수의 일종
• 변수를 초기화 하지 않으면 임의의 값(쓰레기 값)이 저장
97
/* local variable 1 */
#include <stdio.h>
int main() {
f1();
}
void f1() {
int
count;
/* local variable */
for (count=0; count<10; count++) f2();
}
void f2() {
int
count;
/* local variable */
for (count=0; count<10; count++)
printf(“%d”, count);
}
98
/* local variable 2 */
#include <stdio.h>
int main() {
int
i;
for (i=0; i<10; i++) {
if (i==5) {
int
j;
/* local variable */
/* local variable */
j = i * 10;
printf(“%d%”, j);
}
}
}
99
/* local variable 3 */
#include <stdio.h>
void main()
{
printf(“This program won’t compile”);
int
i;
/* ERROR */
i = 10;
printf(“%d”, i);
}
100
/* local variable 4 */
#include <stdio.h>
int
sum(int i);
void main() {
int
i;
for (i=0; i<10; i++)
printf(“%d”, sum(i));
}
int sum(int i) {
int
total;
total = total + i;
return total;
}
101
변수의 선언 위치(2)
• 전역(global) 변수
• 함수 외부에서 선언
• 프로그램 전체에 걸쳐 유효
• 영구적(permanent)
• 프로그램이 실행 되는 동안 변수내의 값을 유지
• 프로그램의 실행이 종료 될 때 까지 기억장소 유지
• 프로그램 시작 시 한번만 초기화
• 지역 변수는 함수가 실행 될 때마다 초기화
• 상수(constant)만을 사용하여 초기화
• 지역 변수는 상수, 변수, 함수 호출을 통해서도 초기화 가능
• 변수를 초기화 하지 않으면 자동으로 0으로 초기화
102
/* global variable 1 */
#include <stdio.h>
int
total;
int
sum(int i);
/* global variable */
void main() {
int
i;
for (i=0; i<10; i++)
printf(“%d”, sum(i));
}
int sum(int i) {
total = total + i;
return total;
}
103
/* global variable 2 */
#include <stdio.h>
int
count;
/* global variable */
void f1() {
int
count;
/* local variable */
count = 100;
printf(“count in f1() : %d”, count);
}
void main() {
count = 10;
f1();
printf(“count in main() : %d”, count);
}
104
/* global variable 3 */
#include <stdio.h>
int
x = 10;
/* global variable */
int myfunc(int i) {
return i/2;
}
void main() {
int
y = x;
int
/* local variable */
z = myfunc(y);/* local variable */
printf(“%d %d”, y, z);
}
105
형 수정자
• 변수가 어떻게 저장될 것인가를 결정
수정자
설 명
auto
자동 변수(임시 변수, 지역 변수)를 선언
static
영구적인 지역 변수 또는 지역적인 전역 변수를 선언
extern
현재 선언된 변수가 다른 파일에 정의되어 있음을 의미
register
변수를 CPU의 레지스터에 저장(빠른 접근 가능)
106
static
• 지역 변수
• 변수의 내용이 함수의 호출 사이에서 보존
• 함수의 실행이 끝나도 변수에 저장된 값이 유효
• 지역 변수를 영구 변수로 사용 가능
• 단 한 번의 초기화
• 초기화를 하지 않으면 컴파일러에 의해서 자동으로 초기화
• 일반적인 지역 변수는 함수가 호출 될 때 마다 초기화
• 전역 변수
• 변수가 선언된 같은 파일의 함수에서만 접근 가능
• 변수는 현재 파일에 지역적으로 사용 가능
107
/* local variable 4 - rev */
#include <stdio.h>
int
sum(int i);
void main() {
int
i;
for (i=0; i<10; i++)
printf(“%d”, sum(i));
}
int sum(int i) {
static int total;
/* static local variable */
total = total + i;
return total;
}
108
/* static variable */
#include <stdio.h>
void main() {
int
counter;
for (counter=0; counter<3; ++counter) {
int
temporary = 1;
static int
permanent;
printf(“Temporary %d Permanent %d\n”,
temporary, permanent);
++temporary;
++permanent;
}
}
109
extern
• 외부 변수를 선언
• 현재 선언된 변수가 다른 파일에 정의 되어 있음을 컴파일러에
게 알려줌
• 하나의 변수를 서로 다른 파일에서 공유할 때 사용
110
/* normal global variable */
/* main.c */
#include <stdio.h>
/* ERROR at compile time */
/* count.c */
#include <stdio.h>
int
counter;
void
inc_counter(void);
void
inc_counter(void)
{
++counter;
}
void main()
{
int i;
for(i=0; i<10; i++)
inc_counter();
printf(“%d\n”, counter);
}
111
/* normal global variable */
/* main.c */
#include <stdio.h>
/* rev. */
/* count.c */
#include <stdio.h>
int
counter;
int
void
inc_counter(void);
void
inc_counter(void)
{
++counter;
}
void main()
{
int i;
counter;
for(i=0; i<10; i++)
inc_counter();
printf(“%d\n”, counter);
}
112
/* normal global variable */
/* main.c */
#include <stdio.h>
/* extern variable */
/* count.c */
#include <stdio.h>
int
counter;
extern int
void
inc_counter(void);
void
inc_counter(void)
{
++counter;
}
void main()
{
int i;
counter;
for(i=0; i<10; i++)
inc_counter();
printf(“%d\n”, counter);
}
113
/* two global variables */
/* main.c */
#include <stdio.h>
/* count.c */
#include <stdio.h>
int
counter;
static int
void
inc_counter(void);
void
inc_counter(void)
{
++counter;
}
void main()
{
int i;
counter;
for(i=0; i<10; i++)
inc_counter();
printf(“%d\n”, counter);
}
114
register
• 변수를 CPU의 레지스터에 저장
• 일반 변수보다 빠른 접근 속도
• 반복을 제어하는 변수, 빈번하게 사용되는 변수 등에서 사용
• 사용상의 제약이 있음
• CPU의 레지스터 수를 초과하면 일반 지역 변수로 취급
• 레지스터를 사용하므로 메모리 주소를 갖지 않음
• & 연산자 사용 불가능
• 전역 변수에는 사용하지 않음
115
/* register variable */
#include <stdio.h>
void main() {
register int
int
j, k;
i, m;
do {
printf(“Enter a value: “);
scanf(“%d”, &i);
m = 0;
for(j=0; j<1; j++)
for(k=0; k<100; k++)
m = k + m;
} while (i>0);
}
116
배열(1)
배열
• 배열(array)이란
• 동일한 데이터들의 연속적인 형태로 사용되는 자료구조
예) “boy” => ‘b’,’o’,’y’
• 물리적으로 인접한 메모리 장소에 저장
• 메모리 관리 및 처리에 효율적
• 배열의 종류
• 배열의 위치를 지정하는 색인(index)에 따라
•
•
•
•
1차원 배열
2차원 배열
3차원 배열
…
118
1차원 배열(1)
• 1차원 배열의 선언
type
array_name[size];
• 정수 배열
int
i[10];
i[0]
i[1]
i[2]
i[3]
i[4]
i[5]
i[6]
i[7]
i[8]
i[9]
i
i+1
i+2
x
x+4
x+8
i+3
x+12
2
i+4
x+16
6
i+5
x+20
0
i+6
x+24
4
i+7
x+28
8
i+8
x+32
2
i+9
x+36
6
※ 배열명 i는 메모리 상에서의 배열의 시작 주소
119
1차원 배열(2)
• 배열의 초기화
int
int
i[5] = {10, 5, 2, 9, 7};
i[] = {10, 5, 2, 9, 7};
i[0]
i[1]
i[2]
i[3]
i[4]
10
5
2
9
7
int
i[5] = {10, 5, 2, };
i[0]
i[1]
i[2]
i[3]
i[4]
10
5
2
0
0
120
/* 예제 8.2 */
#include <stdio.h>
#define M
5
void main()
{
int
int
A[M]={1,2,3,4,5};
i, s=0;
for(i=0; i<M; i++) {
s = s + A[i];
printf("A[%d]=%d\n", i, A[i]);
}
printf("A[M]배열 내용의 합 = %d\n", s);
}
121
/* 예제 8.4 */
#include <stdio.h>
#define
M
void main()
{
int
int
71
i, j, k, gu[M];
index = 0;
for(i=2; i<=9; i++) {
for(j=1; j<=9; j++) {
if(index <= 71) {
gu[index] = i*j;
printf("%d * %d = %d\n", i, j, gu[index]);
}
index++;
}
printf("================\n");
}
}
122
/* 배열의 복사 */
#include <stdio.h>
void main()
{
int
int
int
index;
a[10];
b[10];
for(index = 0; index < 10; index++){
a[index] = index;
}
b = a;
/* error */
for(index = 0; index < 10; index++) {
printf("b[%d] = %d\n", index, b[index]);
}
}
123
/* 배열의 복사 */
#include <stdio.h>
void main()
{
int
int
int
index;
a[10];
b[10];
for(index = 0; index < 10; index++){
a[index] = index;
}
for(index = 0; index < 10; index++) {
b[index] = a[index];
}
/* correct */
for(index = 0; index < 10; index++) {
printf("b[%d] = %d\n", index, b[index]);
}
}
124
1차원 배열(3)
• 문자 배열
• 하나 이상의 문자들의 모임
• 문자열을 위해 사용
• “ “로 표현
• 문자열의 끝을 나타내기 위해 NULL문자 삽입
“park” =>
p
a
r
k
\0
• ‘a’와 “a”의 차이
‘a’
=>
a
“a”
=>
a
\0
125
/* 문자열 출력 1*/
#include <stdio.h>
void main()
{
int
char
i;
str[20];
printf("최대 20자의 문자열을 입력하세요.\n");
gets(str);
/* standard input for string */
for(i=0; str[i]; i++)
printf("%c", str[i]);
printf("\n");
}
126
/* 문자열 출력 2*/
#include <stdio.h>
void main()
{
int
char
i;
str[20];
printf("최대 20자의 문자열을 입력하세요.\n");
gets(str);
/* standard input for string */
printf("%s\n", str);
}
127
/* 예제 8.7 */
#include <stdio.h>
#define
M
20
void str_copy(char a[M], char b[M])
{
int
i = 0;
for(i=0; i<M; i++) b[i] = a[i];
}
void main()
{
int
i;
char A[M] = "Visual C Program";
char B[M];
str_copy(A,B);
for(i=0; i<M; i++)
printf("%c", B[i]);
printf("\n");
}
128
문자열 관련 함수(1)
• 문자열 복사
strcpy(to, from);
/* 문자열 복사*/
#include <stdio.h>
void main()
{
char
str[80];
strcpy(str, “Visual C++”);
printf("%s\n", str);
}
/* 예제 8.7과 비교 */
129
문자열 관련 함수(2)
• 문자열 추가
strcat(to, from);
/* 문자열 추가*/
#include <stdio.h>
void main()
{
char
str[80];
strcpy(str, “Visual C++”);
strcat(str, “ programming”);
printf("%s\n", str);
}
130
문자열 관련 함수(3)
• 문자열 비교
strcmp(s1, s2);
/* 문자열 비교*/
#include <stdio.h>
void main()
{
char
str1[20], str2[20];
strcpy(str1, “Visual C++”);
strcpy(str2, “Visual C++”);
printf("%d\n", strcmp(str1, str2));
}
131
문자열 관련 함수(4)
• 문자열 길이
strlen(str);
/* 문자열 길이*/
#include <stdio.h>
void main()
{
char
str[20];
strcpy(str, “Visual C++”);
printf("%d\n", strlen(str)); /* do not count NULL */
}
132
작성해 보세요.
• 사용자로 부터 10개의 정수를 입력받아 정렬하는 프
로그램을 작성하시오.
• 거품 정렬(bubble sort)
• 인접한 두 수를 비교한다.
• 앞의 수가 뒤의 수보다 크면 두 수의 위치를 바꾼다.
• 모든 원소들이 정렬될 때까지 반복한다.
초기 상태
1 pass
2 pass
3 pass
4 pass
:
:
:
:
:
7
2
2
2
1
2
3
3
1
2
3
7
1
3
6
8
1
7
7
7
1
8
8
8
8
133
/* bubble sort */
#include <stdio.h>
#define
SIZE
void main()
{
int
int
10
item[SIZE];
i, j, t;
for(i=0; i<SIZE; i++)
scanf("%d", &item[i]);
for(i=1; i<SIZE; i++) {
for(j=SIZE-1; j>=i; j--) {
if(item[j-1] > item[j]) { /* 인접한 원소들을 비교 */
t = item[j-1];
item[j-1] = item[j];
item[j] = t;
}
}
}
for(i=0; i<SIZE; i++) printf("%d ", item[i]);
printf("\n");
}
134
작성해 보세요.(Report!)
• 사용자로 부터 10개의 정수를 입력받아 오름차순으로
정렬하는 프로그램을 작성하시오.
• 선택 정렬(selection sort)
• 배열 내에서 가장 작은 원소와 배열의 첫 번째 원소를 교환
• 배열의 정렬되지 않은 나머지 부분을 탐색하여 그 다음 작은 원소
를 찾아 배열의 두 번째 원소를 교환
• 모든 원소들이 정렬될 때까지 반복한다.
초기 상태
1 pass
2 pass
3 pass
4 pass
:
:
:
:
:
20 5
5 20
5
7
5
7
5
7
11
11
11
8
8
7
7
20
20
11
8
8
8
11
20
135
배열(2)
다차원 배열(1)
• 2차원 배열
type
array_name[row-size][col-size];
int
A[3][4];
예)
/* 3X4 array */
A[0][0]
A[0][1]
A[0][2]
A[0][3]
A[1][0]
A[1][1]
A[1][2]
A[1][3]
A[2][0]
A[2][1]
A[2][2]
A[2][3]
A[0][0]
0]
A[0][1]
1]
A[0][2]
2]
A[0][3]
3]
A[1][0]
0]
A[1][1]
1]
A[1][2]
2]
A[1][3]
3]
A[2][0]
0]
A[2][1]
1]
A[2][2]
2]
A[2][3]
3]
137
다차원 배열(2)
• 2차원 배열의 초기화
int
A[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int
A[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
int
A[3][3] = {
1, 2, 3,
4, 5, 6,
7, 8, 9
};
int
A[][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int
A[3][] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
138
/* 예제 8.9*/
#include <stdio.h>
void main()
{
int A[2][3] = {10, 20, 30, 40};
int i, j;
for(i=0; i<2; i++) {
for(j=0; j<3; j++) {
printf(“A[%d][%d] = %d\n”, i, j, A[i][j]);
}
}
}
139
다차원 배열(3)
• 연습문제 8
• 아래의 표를 배열에 대입하고 출력하는 프로그램을 작성하시오.
G
i
r
B
o
y
T
a
l
S
a
y
l
k
140
/* 연습문제 8 */
#include <stdio.h>
void main( )
{
int
char
i;
str[4][4] = { 'G',
'B',
'T',
'S',
};
'i',
'o',
'a',
'a',
'r',
'y',
'l',
'y',
'l',
'\0'
'k',
'\0'
for (i=0; i<4; i++) {
for (j=0; j<4; j++) {
printf(“%c”, str[i][j]);
}
printf(“\n”);
}
}
141
다차원 배열(3)
• 문자열 배열
• 문자열 테이블(string table)
• 일반적인 2차원 배열
char
table[10][40];
• 문자열 입력
gets(table[2]);
• 문자열 출력
printf(“%s\n”,table[2]);
142
/* 연습문제 8 */
#include <stdio.h>
void main()
{
int
i;
char str[4][5];
for (i=0; i<4; i++) {
printf(“%d번째 문자열을 입력하세요.\n”, i);
gets(str[i]);
}
printf("\n");
for (i=0; i<4; i++)
printf("%s\n", str[i]);
}
143
/* 예제 8.10 */
#include <stdio.h>
#defineM
10
int max(int
data[]);
int min(int
data[]);
void main( )
{
int A[M]={122,33,44,11,55,66,77,88,99,502};
int i;
for (i=0; i<M; i++)
printf(“A[%d] = %d “, i, A[i]);
printf(“\n”);
printf(“A[M] 값 중에서 최대값 = %d \n”, max(A));
printf(“A[M] 값 중에서 최소값 = %d \n”, min(A));
}
144
int max(int data[])
{
int i, res = data[0];
for (i=0; i<M; i++)
if (res < data[i])
res = data[i];
return res;
}
int min(int data[])
{
int i, res = data[0];
for (i=0; i< M; i++)
if (res > data[i])
res = data[i];
return res;
}
145
작성해 보세요
• 전자사전 프로그램
• 단어는 5개
• 한글 5개, 영어 5개
• 찾고자하는 단어 입력
• 영어 -> 한글
• 한글 -> 영어
• 테이블에 없는 단어가 입력
되면 “Not in dictionary” 출
력
• “Continue(y/n)?” 출력
• y가 입력되면 계속
• n이 입력되면 종료
146
/* dictionary */
#include <stdio.h>
#include <string.h>
#include <conio.h>
#define FIND 1
void main()
{
char word[5][2][20] = {
"school", "학교",
"computer", "컴퓨터",
"teacher", "선생님",
"book", "책",
"student", "학생"
};
147
char str[20];
char ch;
int
i, status;
while(1) {
status = 0;
printf("Find : ");
gets(str);
for(i=0; i<5; i++) {
if(!strcmp(str, word[i][0])) {
printf("%s\n", word[i][1]);
status = FIND;
break;
}
148
if(!strcmp(str, word[i][1])) {
printf("%s\n", word[i][0]);
status = FIND;
break;
}
}
if(!status)
printf("Not in dictionary.\n");
printf("Continue(y/n)?");
ch = getche();
printf("\n\n");
if (ch=='n'||ch=='N') break;
}
}
149