C 개론 정리
Standard I/O
표준 입출력 함수(1) C 표준 라이브러리에서 제공 키보드 입력, 화면 출력 <stdio.h>에서 정의 함수명 입력 표준 입출력 함수를 사용하기 위해서는 반드시 이 파일을 incldue 시켜야 한다. 함수명 입력 int scanf(“형식지정 문자열”, ¶meter list); 출력 int printf(“형식지정 문자열”, parameter list);
표준 입출력 함수(2) /* 예제 1.7 */ #include <stdio.h> void main(void) { char ch; printf(“한 개의 문자를 입력하시오\n”); scanf(“%c”, &ch); printf(“입력한 값은 =%c\n”, ch); }
표준 입출력 함수(3) 변환 문자 문자 설명 %d 10진수 정수 %o 부호없는 8진수 정수 %x 부호없는 16진수 정수 %u 부호없는 10진수 정수 %lu 부호없는 10진수 long형 정수 %ld 10진수 long형 정수 %c 문자 상수 %s 문자열 %f 실수형 %e 지수형
표준 입출력 함수(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); }
표준 입출력 함수(5) 특수 문자 문자 설명 \n 커서를 한 라인 아래의 첫 번째 열로 이동 \t 탭(tab)의 크기만큼 커서를 이동 \r 커서를 현재 라인의 첫 번째로 열로 이동 \“ “를 출력 \‘ ‘를 출력 \\ \를 출력 \b 커서를 한 컬럼 뒤로 이동(back space) \a 벨소리 발생 \0 NULL
표준 입출력 함수(6) /* 예제 2.3 */ #include <stdio.h> void main(void) { int a; a=67; printf("%C 언어\n", a); }
Variables & Data Type
메모리 Ex) PC133 256MB SDRAM 0과 1의 비트 값을 저장할 수 있는 저장공간 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 256×1024×1024×8 = 21,4748,3648 bits ! 한번에 사용하기에는 너무 큰 용량이므로 적당히 나누어 사용해야 함
변수(1) 메모리에 값을 저장하고 꺼내기 위한 장소를 의미 사용하기 전에 반드시 선언 컴파일러에게 어떤 변수형이 사용되는가를 알려줌 char man = 26; 1 1 1 1 1 1 1 1 man
변수(2) 변수명 규칙 대문자, 소문자, 숫자, 밑줄(_)을 사용 가급적 의미 부여 첫 글자는 반드시 영문자 또는 밑줄(_)로 시작 대,소문자 구별 32문자 길이 예약어는 사용 불가 <표 1.1> 헝가리언 표기법 참고
변수(3) 변수 선언 형식 치환(assignment) 예) int counter; float x,y,z; 선언된 변수에 값을 저장하는 것 예) counter = 100; data-type variabele-name1, variable-name2,,, ; variable-name = value;
자료형(1) 기본 자료형 자료형 크기 키워드 문자 데이터 8bit char 부호 있는 정수 16bit(?) 32bit int 실수 32bit float 배정도 실수 64bit double 값이 없음 void
자료형(2) /* 자료형 크기 */ void main() { char c; int i; float f; double d; printf("size of integer type variable is %d\n", sizeof(i)); printf("size of character type variable is %d\n", sizeof(c)); printf("size of float type variable is %d\n", sizeof(f)); printf("size of double type variable is %d\n", sizeof(d)); }
자료형(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); }
자료형(3) 자료형 수정자 signed unsigned long short char unsigned char int long int
자료형(4) ANSI C 자료형 자료형 크기(bit) 최소범위 char 8 -128~127 unsigned char 0~255 int 16/32 -32,768~32,767 unsigned int 0~65,536 signed int short int 16 unsigned short int signed short int long int 32 -2,147,483,648~ 2,147,483,647 signed long int unsigned long int 0~4,294,967,295 float 3.4x10-38~3.4x10+38 double 64 1.7x10-308~1.7x10+308 long double 80 3.4x10-4932~3.4x10+4932 ANSI C 자료형
자료형(5) 오버플로우(overflow) 프로그램 수행 시, 데이터 값이 변수의 자료형이 허용하는 범위를 넘으면 발생 충분한 범위를 허용하는 자료형으로 선언해야 함 그러나, 무작정 큰 범위의 자료형을 사용하는것 메모리 낭비를 초래 예) short int number = 40960; 예) long int number = 40960;
자료형(6) /* overflow */ #include <stdio.h> void main() { short int i = 32767; printf("%hd %hd %hd\n", i, i+1, i+2); }
자료형(7) 열거형 상수 #define 문 예) #define PI 3.14195 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 PI 3.14195 enum tag { enum-list } #define macro value
자료형(8) typedef 자료형 재정의 예) typedef int integer; typedef 기존 자료형 새로운 자료형;
자료형(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); }
ASCII문자와 진수(1) 진수의 종류 종류 설명 예 10진수 0~9까지의 숫자를 이용 123 8진수 0~7까지의 숫자를 이용 034 16진수 0~9,A~F(a~f)를 이용 0x23
ASCII문자와 진수(2) /* 예제 3.6 */ #include <stdio.h> void main(void) { int i; printf(“8진수를 입력하시오\n”); scanf(“%o”, &i); printf(“입력 코드에 해당하는 문자 %c\n”, i); }
ASCII문자와 진수(3) /* 예제 3.7 */ #include <stdio.h> void main(void) { int i; printf(“16진수를 입력하시오\n”); scanf(“%x”, &i); printf(“입력 코드에 해당하는 문자 %c\n”, i); }
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); }
제어문
프로그램의 구조 순차적 구조 선택 구조 반복 구조 처음부터 순서대로 실행함 { }안의 일반적인 문장들 조건에 따라 대응되는 값으로 분기되어 실행함 if, if~else, switch 반복 구조 어떤 조건이 만족 될 때까지 일정한 명령 또는 문장들을 반복하여 실행함 for, while, do while
if 문 일반 형식 if (condition) { statement1; statement2; .....; } 꽃이_핀다(); } if (봄이_오면) { if(온도>0도) 꽃이_핀다(); }
/* 예제 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");
if ~ else 문 일반 형식 if (condition) { statement1; statement2; .....; }
/* 예제 5.2 */ #include <stdio.h> void main() { int hak; printf("성적을 입력하세요.\n"); scanf("%d", &hak); if(hak>=60) printf("Pass\n"); else printf("Drop\n"); }
switch 문 일반 형식 switch (condition-variable) { case constant1: statement1; .....; break; case constant2: statement2; ..... default: statementn; break; /* omittable */ }
/* 예제 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); case ‘*’: printf("%d %c %d = %d\n", i, opt, j, i*j); case ‘/’: printf("%d %c %d = %d\n", i, opt, j, i/j); }
/* 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"); }
for 문 일반 형식 무한 루프(infinite-loop) for (초기값①;조건식②;증감식③) { statement1; .....; } statement3; for (;;) { .....; }
/* 예제 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);
/* 에제 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;
/* 예제 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) long result = 1; for(i=1;i<=j;i++) result *= i; return result;
/* 재귀함수를 이용한 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;
/* 예제 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”); }
while 문 일반 형식 while(condition) { statement1; .....; }
/* 예제 5.11 */ #include <stdio.h> void main() { int i=1, sum=0; /* i값 초기화 */ while (i<=10){ /* 조건 */ sum = sum + i; i++; /* i값 증가 */ } printf(“1부터 10까지의 합 = %d\n”, sum);
do while 문 일반 형식 do { statement1; .....; } while(condition); /* caution */ statement2;
/* 예제 5.11을 do while로 작성 */ #include <stdio.h> void main() { int i=0, sum=0; /* i값 초기화 */ do { i++; /* i값 증가 */ sum = sum + i; } while (i<10); /* 조건 */ printf(“1부터 10까지의 합 = %d\n”, sum); }
직접 하기!(1) 키보드로부터 정수 하나를 입력 받아서 그 값이 홀수인지 짝수인지를 알려 주는 프로그램을 작성하시오.
직접 하기!(2) 키보드로부터 영문자 하나를 입력받아 자음인지 모음인지를 구별하여 화면에 출력하는 프로그램을 작성 하시오.
직접 하기!(3) 1+1/2+1/3+...+1/10을 구하는 프로그램을 작성하시오. 1+1/2+1/3+...+1/n이 5를 넘는 최초의 n의 값을 구하는 프로그램을 작성하시오.
함수(1)
구조적 프로그래밍(1) Divide & Conquer 모듈(module) 하나의 커다란 작업을 기능적으로 여러 개의 작은 부분으로 나누어 해결하는 기법 문제의 각개 격파 모듈(module) 특정 작업을 수행하는 하나의 작은 Sub-Program C 언어에서는 일반적으로 모듈을 함수 형태로 표현
구조적 프로그래밍(2) 모듈라(modular) 프로그래밍 하나의 프로그램은 관련된 부분(모듈)들로 구성 예) 성적 처리 프로그램 과목의 점수를 입력 받는 모듈(함수) 과목의 평균을 내는 모듈(함수) 계산된 과목의 평균을 출력하는 모듈(함수) Module 1 Module 2 Module 3 Module 4 Module 5 Module 6 Module 2 Module 3 Module 1 구조적으로 잘 설계된 프로그램은 마치 LEGO 블록을 쌓는 것과 유사하다.
구조적 프로그래밍(3) 함수(function) z = f(x,y) 입력 받은 데이터에 대하여 완성된 특정 결과를 발생시키는 일종의 black box 외부로부터 함수로의 인터페이스는 입력과 출력 함수 안의 구체적인 내용은 캡슐화되어 숨겨짐 예) 곱셈 함수 f(x,y) first number result second A * B z = f(x,y) x : first number y : second number z : result
구조적 프로그래밍(4) 함수의 종류 내장 함수 사용자 정의 함수 main() 함수 C 컴파일러와 함께 기본적으로 제공되는 함수들 표준 라이브러리(library) 사용자 정의 함수 사용자가 필요에 따라서 자신의 프로그램에 맞게 작성하는 함수들 main() 함수 프로그램이 실행되면 가장 먼저 실행되는 함수 다른 함수들의 실행순서를 결정해 주는 함수 모든 C 프로그램은 반드시 하나의 main() 함수를 갖는다.
구조적 프로그래밍(5) main() 함수의 예 급여 계산 프로그램 gross_pay() : 총급여를 계산하는 함수 taxes() : 세금을 계산하는 함수 net_pay() : 총 급여에서 세금을 제외한 급여 계산 함수 output() : 결과를 출력하는 함수 taxes( ) net_pay( ) output() gross_pay() 프로그램이 실행되면, 어떠한 순서로 함수가 실행될 것인가?
구조적 프로그래밍(6) main()함수의 예 main() gross_pay( ) taxes( ) net_pay( ) You go first I’m done You go second taxes( ) I’m done You go third net_pay( ) I’m done You go last output( ) I’m done The main() Function Controls All Other Functions
C 프로그램의 구조(1) 하나 이상의 함수로 구성 함수의 머리(header)와 본체(body)로 구성 이중 반드시 하나의 main() 함수가 있어야 한다. 함수의 머리(header)와 본체(body)로 구성 Header : 전처리 기에 대한 문장과 함수 (예:#include) 함수의 이름 함수에 입력되는 값의 데이터형(있을 경우) 함수가 반환하는 값의 데이터형(있을 경우) Body : 중괄호({})로 싸여 블록화
C 프로그램의 구조(2) #include <stdio.h> C 프로그램 int main( ) { …중략… sum( ); printf(“Hello World”); } int sum(void) C 프로그램 헤더(header) : #include main() 함수 그 밖의 함수
함수의 원형과 정의(1) 함수를 사용하기 위해 함수의 원형을 선언 소스 파일 내에서 선언 별도의 헤더 파일(*.h)에 선언 #include <파일명.h> 원형(prototype)을 사용 함으로서 에러를 방지하고 가독성을 높임 컴파일러에게 함수의 반환형 및 매개변수 정보를 전달 type function-name(type parameter1, type parameter2, type parametern);
/* 함수 사용 1 */ #include <stdio.h> int max(int a, int b); void main(void) { ...; max(1,5); //function call } 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
#include <stdio.h> /* 과거의 선언 방법 */ int sum(); void main() { int vol; vol = sum(12, 5, 9, 7); printf("Volume: %d\n", vol); } int sum(int s1, int s2, int s3) return s1+s2+s3; #include <stdio.h> /* 완전한 원형 */ int sum(int s1, int s2, int s3); void main() { int vol; vol = sum(12, 5, 9, 7); printf("Volume: %d\n", vol); } int sum(int s1, int s2, int s3) return s1+s2+s3;
함수의 원형과 정의(2) 가변길이 매개변수 리스트 매개변수의 수가 변하는 함수 가변길이 매개변수를 사용하는 함수의 원형 printf(“The C programming.”); printf(“The %s programming.”, str); int myfunction(int a, ...);
return 문 함수를 호출 한 쪽으로 결과를 반환 함수 수행의 흐름을 변경 return문을 사용하여 값을 반환 함수 수행 도중에 함수의 종료가 가능 return ret-value; return;
/* 예제 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); } B(i);
int A(int a) { return(a=a*2); } int B(int a) if(a<3) return; else printf(“a의 값 = %d\n”, a);
사용자 정의 함수의 종류(1) 매개변수도 없고 리턴 타입도 없는 경우 함수를 호출 할 때 매개변수(파라메터, 인수)가 없음 함수의 실행 결과를 되돌려 주지 않음 void A(void) { …… } B()
#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)
사용자 정의 함수의 종류(2) 매개변수는 있고 리턴 타입은 없는 경우 함수를 호출 할 때 매개변수(파라메터, 인수)가 있음 함수의 실행 결과를 되돌려 주지 않음 void upper_case(char ch);
#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);
사용자 정의 함수의 종류(3) 매개변수는 없고 리턴 타입은 있는 경우 함수를 호출 할 때 매개변수(파라메터, 인수)가 없음 함수의 실행 결과를 되돌려 줌 int sum_a(void);
#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;
사용자 정의 함수의 종류(4) 매개변수도 있고 리턴 타입도 있는 경우 함수를 호출 할 때 매개변수(파라메터, 인수)가 있음 함수의 실행 결과를 되돌려 줌 int input_round(fload a);
#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;
함수(2)
매개 변수의 전달 방식 두 가지로 구분! 값이 그대로 복사되는 값에 의한 호출 방법 원래의 변수의 값은 변하지 않음! 일반 적인 방법 변수의 주소 값이 전달되는 참조에 의한 호출 방법 원래의 변수의 값을 변경 할 수 있음 특수한 경우!
매개 변수 매개 변수 전달 방법 값에 의한 호출 참조에 의한 호출 인수의 값(value)이 함수의 형식 매개 변수에 복사 함수의 매개 변수에서 일어나는 변화가 인수에 영향을 미치지 않음 call by value 참조에 의한 호출 인수의 주소(reference)가 함수의 형식 매개변수에 복사 매개변수에서 일어나는 변화가 인수에 영향을 미침 call by reference
/* call by value */ #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); } int temp; temp = num1; num1 = num2; num2 = temp; /* 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); } int temp; temp = *num1; *num1 = *num2; *num2 = temp;
Call by Value(1) num1 num2 100 500 int num1, int num2; 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
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 num1 num2 swap(num1, num2); /* 값이 복사 */ 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 100 500 100 500
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
Call by Reference(1) num1 num2 100 500 int num1, int num2; 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
Call by Reference(2) 100 500 num1 num2 100 500 10 14 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 num1 num2 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
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
재귀 함수 자기 자신을 다시 호출하는 함수 순환(recursion) 함수 매개 변수와 지역적인 데이터를 스택(stack)에 저장 함수가 순환적으로 호출될 때, 그 함수는 새로운 매개 변수와 지역 변수를 가지고 실행 함수를 구성하는 실행 명령 부분은 오직 하나만 존재 함수 내에서 하나의 조건문이 필요 순환의 진행 여부를 판단 일반적으로 자주 사용되지는 않으나 특정 알고리즘을 단순화 시키는데 매우 유용
/* 재귀 함수 1*/ #include <stdio.h> void recurse(int i); void main() { recurse(0); } void recurse(int i) if(i<10) { recurse(i+1); /* recursive call */ printf(“%d”, i);
/* 재귀 함수 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’;
/* 재귀 함수 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);
/* 재귀 함수 4*/ #include <stdio.h> int factorial(int i) void main() { int num; scanf(“%d”, &num); printf(“%d factorial is %d\n”, num, factorial(num)); } if(i == 1) return 1; else return i * factorial(i-1);
/* 예제 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); } // 다음 페이지 계속
void swap_a(int m, int n) { int temp; temp = m; m = n; n = temp; } void swap_b(int *m, int *n) temp = *m; *m = *n; *n = temp;
/* 예제 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));
/* 예제 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); }
/* 예제 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;
기억부류
변수의 종류 자료의 형태에 따른 분류 기억 부류(변수에 저장되는 값이 프로그램에 미치는 범위)에 따른 분류 int, float, double, char … 기억 부류(변수에 저장되는 값이 프로그램에 미치는 범위)에 따른 분류 자동 변수, 외부 변수, 전역 변수, 정적 변수, 레지스터 변수
기억 부류 변수에 저장되어 있는 값의 유효 범위(scope) 선언 위치에 따른 종류 수정자에 따른 종류 값이 얼마동안 기억장소에 기억되어 있는 가를 결정 변수의 선언 위치 및 사용되는 수정자에 따라 결정 선언 위치에 따른 종류 지역변수(local) 전역변수(global) 수정자에 따른 종류 자동변수(auto) 외부변수(extern) 정적변수(static) 레지스터(register)
변수의 선언 위치(1) 지역(local) 변수 함수 내부에 선언 함수 내부에서만 참조 반드시 블럭의 시작부분에서 선언 함수 내부에서만 참조 다른 함수에서 동일한 변수 이름 사용 가능 임시적(temporary) 변수가 선언된 함수가 실행 될 때만 유효 함수가 끝나면 기억장소에서 소멸 함수의 매개변수도 지역변수의 일종 변수를 초기화 하지 않으면 임의의 값(쓰레기 값)이 저장
/* local variable 1 */ #include <stdio.h> int main() { f1(); } void f1() { int count; /* local variable */ for (count=0; count<10; count++) f2(); void f2() { for (count=0; count<10; count++) printf(“%d”, count);
/* local variable 2 */ #include <stdio.h> int main() { int i; /* local variable */ for (i=0; i<10; i++) { if (i==5) { int j; /* local variable */ j = i * 10; printf(“%d%”, j); }
/* local variable 3 */ #include <stdio.h> void main() { printf(“This program won’t compile”); int i; /* ERROR */ i = 10; printf(“%d”, i); }
/* 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;
변수의 선언 위치(2) 전역(global) 변수 함수 외부에서 선언 프로그램 전체에 걸쳐 유효 영구적(permanent) 프로그램이 실행 되는 동안 변수내의 값을 유지 프로그램의 실행이 종료 될 때 까지 기억장소 유지 프로그램 시작 시 한번만 초기화 지역 변수는 함수가 실행 될 때마다 초기화 상수(constant)만을 사용하여 초기화 지역 변수는 상수, 변수, 함수 호출을 통해서도 초기화 가능 변수를 초기화 하지 않으면 자동으로 0으로 초기화
/* global variable 1 */ #include <stdio.h> int total; /* global variable */ int sum(int i); void main() { int i; for (i=0; i<10; i++) printf(“%d”, sum(i)); } int sum(int i) { total = total + i; return total;
/* 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);
/* global variable 3 */ #include <stdio.h> int x = 10; /* global variable */ int myfunc(int i) { return i/2; } void main() { int y = x; /* local variable */ int z = myfunc(y); /* local variable */ printf(“%d %d”, y, z);
형 수정자 변수가 어떻게 저장될 것인가를 결정 수정자 설 명 auto 자동 변수(임시 변수, 지역 변수)를 선언 static 설 명 auto 자동 변수(임시 변수, 지역 변수)를 선언 static 영구적인 지역 변수 또는 지역적인 전역 변수를 선언 extern 현재 선언된 변수가 다른 파일에 정의되어 있음을 의미 register 변수를 CPU의 레지스터에 저장(빠른 접근 가능)
static 지역 변수 전역 변수 변수의 내용이 함수의 호출 사이에서 보존 단 한 번의 초기화 함수의 실행이 끝나도 변수에 저장된 값이 유효 지역 변수를 영구 변수로 사용 가능 단 한 번의 초기화 초기화를 하지 않으면 컴파일러에 의해서 자동으로 초기화 일반적인 지역 변수는 함수가 호출 될 때 마다 초기화 전역 변수 변수가 선언된 같은 파일의 함수에서만 접근 가능 변수는 현재 파일에 지역적으로 사용 가능
/* 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;
/* 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; }
extern 외부 변수를 선언 현재 선언된 변수가 다른 파일에 정의 되어 있음을 컴파일러에게 알려줌 하나의 변수를 서로 다른 파일에서 공유할 때 사용
/* normal global variable */ /* main.c */ #include <stdio.h> int counter; void inc_counter(void); void main() { int i; for(i=0; i<10; i++) inc_counter(); printf(“%d\n”, counter); } /* ERROR at compile time */ /* count.c */ #include <stdio.h> void inc_counter(void) { ++counter; }
/* normal global variable */ /* main.c */ #include <stdio.h> int counter; void inc_counter(void); void main() { int i; for(i=0; i<10; i++) inc_counter(); printf(“%d\n”, counter); } /* rev. */ /* count.c */ #include <stdio.h> int counter; void inc_counter(void) { ++counter; }
/* normal global variable */ /* main.c */ #include <stdio.h> int counter; void inc_counter(void); void main() { int i; for(i=0; i<10; i++) inc_counter(); printf(“%d\n”, counter); } /* extern variable */ /* count.c */ #include <stdio.h> extern int counter; void inc_counter(void) { ++counter; }
/* two global variables */ /* main.c */ #include <stdio.h> int counter; void inc_counter(void); void main() { int i; for(i=0; i<10; i++) inc_counter(); printf(“%d\n”, counter); } /* count.c */ #include <stdio.h> static int counter; void inc_counter(void) { ++counter; }
register 변수를 CPU의 레지스터에 저장 일반 변수보다 빠른 접근 속도 사용상의 제약이 있음 반복을 제어하는 변수, 빈번하게 사용되는 변수 등에서 사용 사용상의 제약이 있음 CPU의 레지스터 수를 초과하면 일반 지역 변수로 취급 레지스터를 사용하므로 메모리 주소를 갖지 않음 & 연산자 사용 불가능 전역 변수에는 사용하지 않음
/* register variable */ #include <stdio.h> void main() { register int j, k; int 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); }
배열(1)
배열 배열(array)이란 동일한 데이터들의 연속적인 형태로 사용되는 자료구조 예) “boy” => ‘b’,’o’,’y’ 물리적으로 인접한 메모리 장소에 저장 메모리 관리 및 처리에 효율적 배열의 종류 배열의 위치를 지정하는 색인(index)에 따라 1차원 배열 2차원 배열 3차원 배열 …
1차원 배열(1) 1차원 배열의 선언 정수 배열 i[0] i[1] i[2] i[3] i[4] i[5] i[6] i[7] 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 i+3 i+4 i+5 i+6 i+7 i+8 i+9 x x+4 x+8 x+12 x+16 x+20 x+24 x+28 x+32 x+36 ※ 배열명 i는 메모리 상에서의 배열의 시작 주소
1차원 배열(2) 배열의 초기화 i[0] i[1] i[2] i[3] i[4] 10 5 2 9 7 i[0] i[1] i[2] int i[5] = {10, 5, 2, 9, 7}; int 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
/* 예제 8.2 */ #include <stdio.h> #define M 5 void main() { int A[M]={1,2,3,4,5}; int 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);
/* 예제 8.4 */ #include <stdio.h> #define M 71 void main() { int i, j, k, gu[M]; int 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");
/* 배열의 복사 */ #include <stdio.h> void main() { int index; int a[10]; int 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]);
/* 배열의 복사 */ #include <stdio.h> void main() { int index; int a[10]; int b[10]; for(index = 0; index < 10; index++){ a[index] = index; } for(index = 0; index < 10; index++) { b[index] = a[index]; /* correct */ printf("b[%d] = %d\n", index, b[index]);
1차원 배열(3) 문자 배열 하나 이상의 문자들의 모임 문자열을 위해 사용 p a r k \0 a a \0 “ “로 표현 문자열의 끝을 나타내기 위해 NULL문자 삽입 “park” => ‘a’와 “a”의 차이 ‘a’ => “a” => p a r k \0 a a \0
/* 문자열 출력 1*/ #include <stdio.h> void main() { int i; char str[20]; printf("최대 20자의 문자열을 입력하세요.\n"); gets(str); /* standard input for string */ for(i=0; str[i]; i++) printf("%c", str[i]); printf("\n"); }
/* 문자열 출력 2*/ #include <stdio.h> void main() { int i; char str[20]; printf("최대 20자의 문자열을 입력하세요.\n"); gets(str); /* standard input for string */ printf("%s\n", str); }
/* 예제 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");
문자열 관련 함수(1) 문자열 복사 strcpy(to, from); /* 문자열 복사*/ #include <stdio.h> void main() { char str[80]; strcpy(str, “Visual C++”); /* 예제 8.7과 비교 */ printf("%s\n", str); }
문자열 관련 함수(2) 문자열 추가 strcat(to, from); /* 문자열 추가*/ #include <stdio.h> void main() { char str[80]; strcpy(str, “Visual C++”); strcat(str, “ programming”); printf("%s\n", str); }
문자열 관련 함수(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)); }
문자열 관련 함수(4) 문자열 길이 strlen(str); /* 문자열 길이*/ #include <stdio.h> void main() { char str[20]; strcpy(str, “Visual C++”); printf("%d\n", strlen(str)); /* do not count NULL */ }
작성해 보세요. 사용자로 부터 10개의 정수를 입력받아 정렬하는 프로그램을 작성하시오. 거품 정렬(bubble sort) 인접한 두 수를 비교한다. 앞의 수가 뒤의 수보다 크면 두 수의 위치를 바꾼다. 모든 원소들이 정렬될 때까지 반복한다. 초기 상태 : 7 2 3 8 1 1 pass : 2 3 7 1 8 2 pass : 2 3 1 7 8 3 pass : 2 1 3 7 8 4 pass : 1 2 6 7 8
/* bubble sort */ #include <stdio.h> #define SIZE 10 void main() { int item[SIZE]; int 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");
작성해 보세요.(Report!) 사용자로 부터 10개의 정수를 입력받아 오름차순으로 정렬하는 프로그램을 작성하시오. 선택 정렬(selection sort) 배열 내에서 가장 작은 원소와 배열의 첫 번째 원소를 교환 배열의 정렬되지 않은 나머지 부분을 탐색하여 그 다음 작은 원소를 찾아 배열의 두 번째 원소를 교환 모든 원소들이 정렬될 때까지 반복한다. 초기 상태 : 20 5 11 7 8 1 pass : 5 20 11 7 8 2 pass : 5 7 11 20 8 3 pass : 5 7 8 20 11 4 pass : 5 7 8 11 20
배열(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] 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]
다차원 배열(2) 2차원 배열의 초기화 int A[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
/* 예제 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]); }
다차원 배열(3) 연습문제 8 아래의 표를 배열에 대입하고 출력하는 프로그램을 작성하시오. G i r l B o y T a k S
/* 연습문제 8 */ #include <stdio.h> void main( ) { int i; char str[4][4] = { 'G', 'i', 'r', 'l', 'B', 'o', 'y', '\0' 'T', 'a', 'l', 'k', 'S', 'a', 'y', '\0' }; for (i=0; i<4; i++) { for (j=0; j<4; j++) { printf(“%c”, str[i][j]); } printf(“\n”);
다차원 배열(3) 문자열 배열 문자열 테이블(string table) 일반적인 2차원 배열 char table[10][40]; 문자열 입력 문자열 출력 char table[10][40]; gets(table[2]); printf(“%s\n”,table[2]);
/* 연습문제 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]);
/* 예제 8.10 */ #include <stdio.h> #define M 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)); }
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[]) for (i=0; i< M; i++) if (res > data[i])
작성해 보세요 전자사전 프로그램 단어는 5개 찾고자하는 단어 입력 “Continue(y/n)?” 출력 한글 5개, 영어 5개 영어 -> 한글 한글 -> 영어 테이블에 없는 단어가 입력되면 “Not in dictionary” 출력 “Continue(y/n)?” 출력 y가 입력되면 계속 n이 입력되면 종료
/* 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", "학생" };
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; }
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;