Chapter 5 – 제어의 흐름 Outline 5.1 문장의 종류 5.2 택일문 5.3 반복문 5.4 분기문 5.5 요약 5.1 문장의 종류 5.2 택일문 5.3 반복문 5.4 분기문 5.5 요약 5.6 예제
5.1 문장의 종류 S1; S2; 단문(短文, single statement) 중문(重文, compound statement) 5.1 문장의 종류 S1; S2; 문장의 끝은 ;으로 알리고 S1 수행 후 S2로 순차 처리된다. 단문(短文, single statement) ; 으로 종료되는 한 개의 문장 (예1) x++; (예2) a = b; 중문(重文, compound statement) {와 } 사이에 수 개의 문장을 열거하여 만든 블록 공문(空文, empty statement) ; 만으로 이루어진 문장으로 아무 일도 하지 않는다. /* 중문의 예 */ { x++; a = b; }
5.1 문장의 종류 그림 5.1 문장의 종류 전처리기 지시문 #define, #include 등 5.1 문장의 종류 그림 5.1 문장의 종류 전처리기 지시문 #define, #include 등 문법상으로는 문장이 아닌 제어 문장 선언문 char, int, double … 제어문 택일문 : if, if – else, switch – case 문 반복문 : while, for, do – while 문 분기문 : goto, return, break, continue 문 기타 콤마 : 문법적으로는 분리자 단문 : 세미콜론으로 끝나는 1 개의 문장 복문 : {과 } 사이에 열거된 문장들 공문 : 문법적으로는 분리자.
5.2 택일문 단일 택일문 if if (수식) 문장1 어느 수식에 대해서나 참, 거짓이 결정된다. 0 - 거짓 5.2 택일문 단일 택일문 if if (수식) 문장1 /* 예문 */ if (grade >= 90) printf(“\nCongratulations!”); 참 거짓 수식? 문 장 1 어느 수식에 대해서나 참, 거짓이 결정된다. 0 - 거짓 0 이외의 값 – 참 (예) 수식이 (2 – 5) 이면 참
5.2 택일문 (예 5.1) if 문의 사용 예 (1) 옳은 예 if (grade >= 90) printf(“\nCongratulations!”); if (x != 0.0) y /= x; if (c == ‘ ’) { blank_no++; printf(“\nanother blank found”); } - 3번째 예에서는 수식으로 c == ‘ ’을, 문장1로 중문을 사용하고 있다.
5.2 택일문 (예 5.1 계속) if 문의 사용 예 (2) 틀린 예 if b == a /* 괄호가 빠졌음 */ 5.2 택일문 (예 5.1 계속) if 문의 사용 예 (2) 틀린 예 if b == a /* 괄호가 빠졌음 */ area = a * a; if (c !=EOF && ‘a’ <= c && c <= ‘z’) c = c – ‘a’ + ‘A’ /* ;이 빠졌음 */ - 첫 if 문에서는 수식을 감싸는 괄호가 없다. - 둘째 if 문에서는 ;이 없으므로 문장이 아니다.
5.2 택일문 if (수식) 문장1 else 문장2 양자 택일문 if-else x = a – b; else x = b – a; 5.2 택일문 양자 택일문 if-else if (수식) 문장1 else 문장2 /* 예문 */ if (a > b) x = a – b; else x = b – a; 거짓 참 문 장 1 문 장 2 수식?
5.2 택일문 (예 5.2) if-else 문의 예 if (a > b) x = a – b; else x = b – a; 5.2 택일문 (예 5.2) if-else 문의 예 /* (1) */ if (a > b) x = a – b; else x = b – a; /* (2) */ if (c == ‘e’) e_cnt++; other_cnt++; /* (3) */ if (c >= ‘a’ && c <= ‘z’) /* 소문자 누계 */ lower_cnt++;
5.2 택일문 문장1을 잘못 사용한 예 if (i != j) { i = 1; j = 2; }; else i += j; 5.2 택일문 문장1을 잘못 사용한 예 /* 구문 에러 */ if (i != j) { i = 1; j = 2; }; else i += j; [해 설] - else 직전의 ; 이 공문으로 처리되어 else는 if와 쌍을 이루지 못한다. - else로 시작하는 문장으로 보고 컴파일 에러 처리됨. [해 결] 중괄호 후의 ;를 제거해야 한다.
5.2 택일문 dangling else problem if (basic_math >= 90) 5.2 택일문 dangling else problem /* dangling else problem */ if (basic_math >= 90) if (math >= 90) printf(“\nExcellent student\n”); else printf(“\nGood student\n”); [해 설] dangling else problem (질문) else문이 2개의 if 중 어느 것과 쌍을 이루는가? (답) C언어에서는 가장 안쪽의 if(즉 둘째 if)와 쌍을 이룸
dangling else problem(계속) 5.2 택일문 dangling else problem(계속) /* dangling else problem */ if (basic_math >= 90) { if (math >= 90) printf(“\nExcellent student\n”); else printf(“\nGood student\n”); } [해 설] C 언어에서는 {와 }를 생략해도 그 의미는 위와 같다. 즉 C 언어의 dangling else problem은 항상 else와 가장 가까운 (즉 가장 안쪽의) if와 짝을 이루는 것으로 처리된다.
5.2 택일문 if (수식1) 문장1 else if (수식2) 문장2 ⋮ else if (수식n) 문장n else 문장n+1 5.2 택일문 if-else 문의 조합 if (수식1) 문장1 else if (수식2) 문장2 ⋮ else if (수식n) 문장n else 문장n+1 if (c == ‘ ’ || c == ‘\t’) blank_cnt++; /* 공백 누계 */ else if (c >= ‘0’ && c <= ‘9’) digit_cnt++; /* 숫자 누계 */ else if (c >= ‘a’ && c <= ‘z’ || c >= ‘A’ && c <= ‘B’) letter_cnt++; /* 대소문자 누계 */ else if (c == ‘\n’) nl_cnt++; /* 새줄 기호 누계 */ else other_cnt++; [예 5.3] if 문과 if-else 문의 조합
if-else문장을 조건 연산자(?와 :)로 표현 5.2 택일문 if-else문장을 조건 연산자(?와 :)로 표현 if (x > y) z = x; else z = y; z = x > y ? x : y; - 위의 두 문장은 같은 표현이다.
if-else문장을 조건 연산자로 표현(계속) 5.2 택일문 if-else문장을 조건 연산자로 표현(계속) if (a > b) c = 1; else if (a < b) c = 2; else c = 3; c = (a > b) ? 1 : ((a < b) ? 2 : 3); - 위의 두 문장은 같은 표현이다. - 조건 연산자 ?와 :이 우결합성을 가지므로 다음과 같다. c = (a > b) ? 1 : (a < b) ? 2 : 3;
5.2 택일문 ⋮ switch (수식) { switch-case 문 case 정수형수식1: 문장리스트1; 5.2 택일문 switch-case 문 int s; char gr; ⋮ switch (s / 10) { case 10: gr = ‘A’; case 9: case 8: gr = ‘B’; case 7: gr = ‘C’; case 6: gr = ‘D’; default: gr = ‘F’; } [예 5.4] switch-case switch (수식) { case 정수형수식1: 문장리스트1; case 정수형수식2: 문장리스트2; ⋮ case 정수형수식n: 문장리스트n; default: 문장리스트n+1; } - s값이 87이라면 s/10의 결과가 8이므로 gr에 ‘B’가 배정된다. 그러나 그 후 다음 문장을 차례로 수행하여 결국 gr에는 ‘F’가 저장 각 문장리스트의 마지막 문장으로 break를 사용하면 각 문장리스트 수행 후 switch 문을 빠져 나올 수 있다.
5.2 택일문 ⋮ switch (수식) { switch-case 문(break사용) case 정수형수식1: 문장리스트1; 5.2 택일문 switch-case 문(break사용) int s; char gr; ⋮ switch (s / 10) { case 10: gr = ‘A’; break; case 9: case 8: gr = ‘B’; break; case 7: gr = ‘C’; break; case 6: gr = ‘D’; break; default: gr = ‘F’; } [예 5.5] switch-case (break사용) switch (수식) { case 정수형수식1: 문장리스트1; break; case 정수형수식2: 문장리스트2; ⋮ case 정수형수식n: 문장리스트n; default: 문장리스트n+1; } s값이 87이라면 s/10의 결과가 8이므로 gr에 ‘B’가 배정된 후 break 수행으로 즉시 switch 문장을 빠져나간다.
5.2 택일문 switch-case 문(break사용) : 계속 [예 5.5 계속] switch-case (break사용) 5.2 택일문 switch-case 문(break사용) : 계속 [예 5.5 계속] switch-case (break사용) case 10: gr = ‘A’; break; case 9: case 10: case 9: gr = ‘A’; break; case 10의 문장들과 case 9의 문장들이 동일하므로 좌측의 코드를 우측과 같이 바꿀 수 있다.
5.2 택일문 switch-case 문(break사용) : 계속 5.2 택일문 switch-case 문(break사용) : 계속 참 거짓 . 정수형수식 1 문장리스트1 break 정수형수식 2 문장리스트2 정수형수식 n 문장리스트n 문장리스트n+1 switch-case 문은 통상 break를 써서 위와 같은 식으로 동작한다.
5.3 반복문 while문 while (수식) 문장 sum = sum + n; /* 예문 */ while (--n) 수식? 5.3 반복문 while문 while (수식) 문장 /* 예문 */ while (--n) sum = sum + n; 수식? 문 장 참 거짓
5.3 반복문 (예 5.6) while 문의 사용 예(1) 옳은 예 틀린 예 /* (1) 옳은 예*/ 5.3 반복문 (예 5.6) while 문의 사용 예(1) /* (1) 옳은 예*/ #define EOF -1 int c; while ((c = getchar()) != EOF) { if (c >= ‘a’ && c <= ‘z’) /* 소문자 누계 */ lower_cnt++; total_cnt++; } /* (2) 틀린 예*/ while (++i < 1000) do { /* do가 포함되어서는 안 됨 */ j = 2 * i + 3; printf(“\n%d”, j); 옳은 예 틀린 예
5.3 반복문 (예 5.7) while 문의 사용 예(2) /* (1) */ int i, a[100]; i = 0; while (i < 100) { a[i] = 0; i++; } 100개의 원소를 가진 배열의 각 원소 a[0],a[1],…a[99]의 값을 0으로 초기화 앞으로 배울 for 문을 이용하면 간결한 표현이 가능함
5.3 반복문 (예 5.7 계속) n의 factorial을 구한다. 가령 n이 5이면, 1부터 5까지 차례로 5.3 반복문 (예 5.7 계속) /* (2) */ int n, i, factorial; n = 5; i = 1; factorial = 1; while (i <= n) { factorial = factorial * i; i++; } n의 factorial을 구한다. 가령 n이 5이면, 1부터 5까지 차례로 factorial에 곱해진다. factorial = factorial * i; 대신 factorial *= i;로 표기 가능
5.3 반복문 (예 5.7 계속) n값이 감소되면서 sum = sum + n;을 수행 5.3 반복문 (예 5.7 계속) /* (3) n보다 작은 자연수의 합*/ int n, sum = 0; printf(“\ninput an integer: ”); scanf(“%d”, &n); while (--n) sum = sum + n; printf(“\nResult is %d.”, sum); n값이 감소되면서 sum = sum + n;을 수행 가령 n이 5이면, 4,3,2,1이 차례로 더해져 결국 sum은 10이 됨 n이 초반에 음수였다면 무한 순환(infinite loop)에 빠짐 (해결책) n이 음수면 처음부터 while문을 빠져 나오게 함 while (--n) sum = sum + n; while (--n >= 0) sum = sum + n;
5.3 반복문 while 반복문에 공문을 사용한 예 getchar()로 읽어 c에 배정한 문자가 공백 문자인 동안 5.3 반복문 while 반복문에 공문을 사용한 예 /* 공문의 사용 */ while ((c = getchar()) == ‘ ’) ; /* 공문(null statement) */ getchar()로 읽어 c에 배정한 문자가 공백 문자인 동안 계속 읽어 들인다. while문의 몸체가 비어있음에 주의.
5.3 반복문 for문 for (수식1; 수식2 ; 수식3) 문장 sum = sum + i; 5.3 반복문 for문 for (수식1; 수식2 ; 수식3) 문장 /* 예문 */ for (i = 1; i <= 10; i++) sum = sum + i; for(초기값; 최종값; 증감값) { 반복내용 } 수 식 1 수 식 2 참 문 장 수 식 3 거짓
5.3 반복문 (예 5.8) for 문의 사용 예 for( ; ; ) 문장; for( ; 최종값 ; ) 문장; 5.3 반복문 (예 5.8) for 문의 사용 예 for( ; ; ) 문장; for( ; 최종값 ; ) 문장; 주의 : 최종값이 생략되면 무한 루프 루프의 탈출 : break, goto, return 옳은 예 [설 명] /* (1) 옳은 예*/ for (i = 1, factorial = 1; i <= n; i++) factorial = factorial * i; for 직후의 ()안에는 반드시 ;이 2개 있어야 한다. 수식1은 i = 1, factorial = 1 이다. 수식2는 i <= n 이며, 참이면 문장 factorial = factorial * i; 을 수행하고, 수식3 i++를 수행한 후, 다시 수식2를 테스트한다. 거짓이면 for문을 종료한다.
5.3 반복문 (예 5.8 계속) (1) 을 for 문 없이 표현 factorial = factorial * 1; 5.3 반복문 (예 5.8 계속) (1) 을 for 문 없이 표현 옳은 예를 for 없이 표현 : n 이 5일 때 [설 명] /* (1) 옳은 예를 n이 5인 경우 for문장 없이 표현 */ factorial = 1; factorial = factorial * 1; factorial = factorial * 2; factorial = factorial * 3; factorial = factorial * 4; factorial = factorial * 5; n이 5 라면 전의 for문은 위와 같이 바꿀 수 있다. 결국 factorial에 120이 저장됨 [참고] n이 100이면 어떤가?
5.3 반복문 (예 5.8 계속) for 문의 사용 예 sum += i; (2) 틀린 예 5.3 반복문 (예 5.8 계속) for 문의 사용 예 /* (2) 틀린 예*/ for (i = 0, i < n, i += 3) /* 세미콜론이 필요 함 */ sum += i; (2) 틀린 예 for 직후의 ()안에는 반드시 ;이 2개 있어야 한다.
(예) while 문을 for문으로 간결히 표현 5.3 반복문 (예) while 문을 for문으로 간결히 표현 /* 예 5-7 (1) */ int i, a[100]; i = 0; while (i < 100) { a[i] = 0; i++; } /* for 사용한 코딩 */ int i, a[100]; for (i = 0; i < 100; i++) a[i] = 0; 100개의 원소를 가진 배열의 각 원소 a[0],a[1],…a[99]의 값을 0으로 초기화 for문은 루프에 들어가기 전에 수행할 문장을 수식1로 표현하고, 루프내의 본문 수행 후 항상 수행하는 문장은 수식3으로 표현함.
5.3 반복문 (예 5-9) 1부터 10까지의 합 계산(1) (1)이 가장 흔히 사용되는 방식이다. 5.3 반복문 (예 5-9) 1부터 10까지의 합 계산(1) int i, sum; /* (1) */ sum = 0; for (i = 1; i <= 10; i++) sum = sum + i; int i, sum; /* (2) */ sum = 0; i = 1; for (; i <= 10; i++) sum = sum + i; int i, sum; /* (3) */ sum = 0; i = 1; for (; i <= 10;) sum = sum + i++; (1)이 가장 흔히 사용되는 방식이다. (2)에서는 수식1이 for문 전으로 나온 형태이다. (3)에서는 수식3을 문장 내에 추가하였다. (3)에서 sum = sum + i++;대신 다음으로 바꾸어도 된다. { sum = sum + i; i++; }
5.3 반복문 (예 5-10) 1부터 10까지의 합 계산(2) int i, sum; /* (1) */ for (sum = 0, i = 1; i <= 10; sum = sum + i, i++) ; /* 공 문 */ for 문에 들어가기 전에 수행하는 문장 2개를 콤마 연사자를 사용하여 한 개의 수식1(sum = 0, i = 1)으로 만들어 사용하였다. for 문의 몸체에 있던 sum = sum + i를 수식3의 일부로 추가하였다. 즉 수식3은 콤마 연산자를 이용한 sum = sum + i, i++이다. 이 for 문에는 공문을 사용하였다. 즉 수식2가 참인 경우 수행하는 for문의 body(몸체)가 없다.
무한 순환(infinite loop)의 형태 5.3 반복문 무한 순환(infinite loop)의 형태 for ( ; ; ) { . . . } while (1) { . . . } for 문과 while 문의 . . . 부분이 무한히 수행된다. 몸체 내에서의 탈출은 break; 문을 사용할 수 있다.
5.3 반복문 do-while문 do 문장 while (수식); 문 장 참 수 식 거 짓 5.3 반복문 do-while문 do 문장 while (수식); /* 예 5.11 do-whle 문의 예 */ do { sum = sum + i; i--; } while (i > 0); 참 거 짓 문 장 수 식
5.4 분기문 분기문의 종류 : goto 문 beak 문 continue 문 return 문 goto 레이블; 5.4 분기문 분기문의 종류 : goto 문 goto 레이블; 레이블은 식별자를 사용한다. 에러처리 외에는 가능하면 goto문 없이 사용하는 것이 좋다. beak 문 continue 문 return 문
5.4 분기문 레이블 문 goto문과 레이블이 같은 다음 형태의 문장이다. 해당 goto문과 동일한 함수 내에 존재해야 한다. 5.4 분기문 레이블 문 goto문과 레이블이 같은 다음 형태의 문장이다. 레이블 : 문장 해당 goto문과 동일한 함수 내에 존재해야 한다. goto 문의 수행 후 제어가 넘어 가는 문장이다. 레이블 문도 문장이므로 다중 레이블이 가능하다. (예 5.12) /* 예 5.12 레이블 문의 사용 */ /* (1) 옳은 예 */ label100: a = b + c; calc_sqrt: x = sqrt(y); msg_error: printf(“error\n”); error1: error2: printf(“error found\n”); /* 다중 레이블 */ /* (2) 틀린 예 */ 100: a = b + c; /* 100은 식별자가 아님 */ ww+xx: x = sqrt(y); /* ww+xx는 식별자가 아님 */ a: a = a + b; /* a는 유일한 식별자가 아님 */
5.4 분기문 goto 문 goto 문을 수행하면 해당 레이블 문으로 제어 흐름이 넘어간다. goto labl; . . . 5.4 분기문 goto 문 goto 문을 수행하면 해당 레이블 문으로 제어 흐름이 넘어간다. (예 5.13) goto labl; . . . labl : /* 예 5.13 goto 문의 사용 */ while (scanf(“%lf”, &x)) { /* lf는 long float 즉 double */ if (x < 0.0) goto minus_warning; printf(“\nSquare root of %f = %f”, x, sqrt(x)); } . . . minus_warning: printf(“\n 음수값 발생”);
5.4 분기문 break 문 switch-case 문과 반복문에서의 명시적 탈출 5.4 분기문 break 문 switch-case 문과 반복문에서의 명시적 탈출 단 반복문은 while 문, for 문, do-while문임 (예 5.14) (1) /* 예 5.14(1) break 문 */ while (1) { scanf(“%lf”, &x); if (x < 0.0) break; printf(“\n%f”, sqrt(x)); . . . } break를 수행하면 while 문을 빠져 나온다.
5.4 분기문 continue 문 반복문(while 문, for 문, do-while문)에서 현 반복 단계를 중지시키고, 다음의 새로운 반복 단계를 실행시키기 위해 사용 (예 5.14) (2) /* 예 5.14(2) continue 문 */ #define TOTAL 1000 . . . for (i = 0; i < TOTAL; ++i) { c = getchar(); if (c >= ‘0’ && c <= ‘9’) continue; /* 남은 문장들 */ } 읽어 들인 문자가 ‘0’에서 ‘9’ 중 하나면, continue가 수행되어, 남은 문장들을 생략하고 다음 i에 대해 for 몸체를 새로이 수행한다.
5.4 분기문 exit 문 프로그램을 종료시킨다. exit의 인수로는 정상 종료인 경우 0을 비정상 종료인 경우 1을 통상 사용한다. (예 5.15) /* 예 5.15 exit() */ if (scanf(“%lf”, &x) != 1) { printf((“No data found!\n”); exit(1); } . . . - scanf가 실패하면 에러메시지를 내고 종료시키고 있다.
5.6 예 제 예제 5.1 output 1 /* File : ex5-1.c 5.6 예 제 1 /* File : ex5-1.c 2 문자를 입력받아 ‘a’이면 A를 출력하고, 아니면 not A를 출력 */ 3 #include <stdio.h> 4 int main(void) 5 { 6 char a; 7 scanf(“%c”, &a); 8 if (a == ‘a’) 9 printf(“A\n”); 8 else 10 printf(“not A\n”); 11 } 예제 5.1 output not A
예제 5.2 [해 설] output c % 2는 c를 2로 나눈 나머지이다. 1 /* File : ex5-2.c 2 4102를 5비트 우로 이동한 후, 그 결과가 짝수이고 100 이상이면 3 그 값을 출력하시오. */ 4 #include <stdio.h> 5 int main(void) 6 { 7 int a = 4102; 8 int c; 9 10 c = a >> 5; 11 if ((c % 2) == 0 && c >= 100) 12 printf(“%d\n”, c); 13 } 예제 5.2 [해 설] output c % 2는 c를 2로 나눈 나머지이다. 128
예제 5.3 output 1 /* File : ex5-3.c 2 정수 3개를 각각 a, b c로 입력받아, 3 b*b – 4*a*c가 양수이면 +, 0이면 0, 음수이면 –를 출력 */ 4 #include <stdio.h> 5 int main(void) 6 { 7 int a, b, c, d; 8 9 printf(“Enter three integers: ”); 10 scanf(“%d %d %d”, &a, &b, &c); 11 d = b * b – 4 * a *c; 12 if (d > 0) 13 printf(“+\n”); 14 else if (d == 0) 15 printf(“0\n”); 16 else 17 printf(“-\n”); 19 } 예제 5.3 output Enter three integers: 5 3 4 -
예제 5.4 output 1 /* File : ex5-4.c 2 정수, 연산자, 정수를 연속으로 입력받아 2 정수, 연산자, 정수를 연속으로 입력받아 3 이를 수행하는 프로그램(연산자는 + - * / 제공) */ 4 #include <stdio.h> 5 int main(void) 6 { 7 char op; 8 int a, b; 9 10 printf(“Enter an expression(e.g. 4*6) : ”); 11 scanf(“%d%c%d”, &a, &op, &b); 12 if (op == ‘+’) 13 printf(“%d+%d=%d\n”, a, b, a + b); 14 else if (op == ‘-’) 15 printf(“%d-%d=%d\n”, a, b, a - b); 16 else if (op == ‘*’) 17 printf(“%d*%d=%d\n”, a, b, a * b); 18 else if (op == ‘/’) 19 printf(“%d/%d=%d\n”, a, b, a / b); 20 else 21 printf(“No such operator %c\n”, op); 22 } 예제 5.4 output Enter an expression(e.g. 4*6) : 5*7 5*7=35
예제 5.5 1 /* File : ex5-5.c 2 정수, 연산자, 정수를 연속으로 입력받아 처리 2 정수, 연산자, 정수를 연속으로 입력받아 처리 3 단, switch 문을 사용하시오. */ 4 #include <stdio.h> 5 int main(void) 6 { 7 char op; 8 int a, b; 9 10 printf(“수식을 입력하시오(예 4*6) : ”); 11 scanf(“%d%c%d”, &a, &op, &b); 12 switch (op) { 13 case ‘+’: 14 printf(“%d+%d=%d\n”, a, b, a + b); 15 break; 16 case ‘-’: 17 printf(“%d-%d=%d\n”, a, b, a - b); 18 break; 19 case ‘*’: 20 printf(“%d*%d=%d\n”, a, b, a * b); 21 break; 22 case ‘/’: 23 printf(“%d/%d=%d\n”, a, b, a / b); 24 break; 25 default: 26 printf(“No such operator %c\n”, op); 27 } 28 } 예제 5.5
1 /* File : ex5-6.c 2 i의 초기값 15에서 시작하여 3씩 감소하면서, i가 음수가 아닌한 3 C Programming이라 새 줄에 출력하는 프로그램을 4 for 문장을 이용하여 작성하시오. */ 5 #include <stdio.h> 6 int main(void) 7 { 8 int i; 9 for (i = 15; i >= 0; i = i – 3) 10 printf(“C Programming\n”); 11 } 예제 5.6 output C Programming
예제 5.7 output 1 /* File : ex5-7.c 2 While 문을 이용하여 2의 10승을 구하는 프로그램 */ 3 #include <stdio.h> 4 int main(void) 5 { 6 int i = 1; 7 int ans = 1; 8 while (i <= 10) { 9 ans = ans * 2; 10 i++; 11 } 12 printf(“2^10=%d\n”, ans); 13 } 예제 5.7 output 2^10=1024
위 for 문장의 수식3은 통상 i++로 사용한다. printf의 첫 인수내의 %2d는 2자리를 잡아 우정렬로 1 /* File : ex5-8.c 2 다음 프로그램의 실행 결과는? */ 3 #include <stdio.h> 4 int main(void) 5 { 6 int i; 7 for (i = 1; i <= 10; i = i + 1) 8 printf(“ %2d”, i); 9 printf(“\n”); 10 } 예제 5.8 [해 설] output 위 for 문장의 수식3은 통상 i++로 사용한다. printf의 첫 인수내의 %2d는 2자리를 잡아 우정렬로 정수를 출력하라는 뜻 1 2 3 4 5 6 7 8 9 10
i값을 바꾸어 반복되는 for 문장 내에 2개의 문장을 수행한다. 한 문장은 j를 바꾸어 반복되는 for문장이고, 1 /* File : ex5-9.c 2 구구단을 9줄로 출력하시오. */ 3 #include <stdio.h> 4 int main(void) 5 { 6 int i, j; 7 for (i = 1; i < 10; i++) { 8 for (j = 1; j < 10; j++) 9 printf(“ %2d”, i*j); 10 printf(“\n”); 11 } 12 } 예제 5.9 [해 설] output i값을 바꾸어 반복되는 for 문장 내에 2개의 문장을 수행한다. 한 문장은 j를 바꾸어 반복되는 for문장이고, 다음 문장은 줄바꿈 문자를 출력한다. 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81
예제 5.10 output 1 /* File : ex5-10.c 2 다음 식을 만족하는 A, B, C, D를 구하시오. 5 + C A C 6 ------- 7 B D D */ 8 #include <stdio.h> 9 int main(void) 10 { 11 int a, b, c, d, sum; 12 for (a = 1; a < 10; a++) 13 for (b = 1; b < 10; b++) 14 for (c = 1; c < 10; c++) 15 for (d = 0; d < 10; d++) { 16 sum = (100 * a + 10 * b + c) + (100 * c + 10 * a + c); 17 if (sum == 100 * b + 10 * d + d) 18 printf(“A=%d B=%d C=%d D=%d\n”, a, b, c, d); 19 } 20 } 예제 5.10 output A=1 B=3 C=2 D=4 A=2 B=6 C=4 D=8 A=2 B=9 C=6 D=2 A=5 B=7 C=1 D=2
do와 while사이의 문장이 수행된 후에는 반드시 (sum <= 1000)여부가 테스트 된다. 1 /* File : ex5-11.c 2 1부터 i까지 각각의 제곱을 더해서 1000을 초과하는 3 가장 작은 I와 그 때의 합을 do-while을 이용하여 구하시오. */ 4 #include <stdio.h> 5 int main(void) 6 { 7 int i = 0, sum = 0; 8 do { 9 i++; 10 sum += i*i; 11 } while (sum <= 1000); 12 printf(“i=%d sum=%d\n”, i, sum); 13 } 예제 5.11 [해 설] output do와 while사이의 문장이 수행된 후에는 반드시 (sum <= 1000)여부가 테스트 된다. 테스트 결과가 참이면 계속 반복문이 수행되고, 거짓이면 종료된다. i=14 sum=1015
예제 5.12 1 /* File : ex5-12.c 2 임의 개의 수를 읽어 들여, 데이터의 수, 최대값, 최소값 및 평균을 2 임의 개의 수를 읽어 들여, 데이터의 수, 최대값, 최소값 및 평균을 3 구하시오. 입력자료가 든 file을 작성하고, 입력방향전환을 이용하여 4 동작시키시오. */ 5 #include <stdio.h> 6 int main(void) 7 { 8 int count; 9 double x, min, max, sum, avg; 10 11 sum = 0; 12 min = 1e30; /* 불가능하게 큰 수로 초기화 */ 13 max = -1e30; /* 불가능하게 작은 수로 초기화 */ 14 count = 0; 15 while (scanf(“%lf”, &x) == 1) { 16 count++; 17 sum += x; 18 if (min > x) 19 min = x; 20 if (max < x) 21 max = x; 22 } 예제 5.12
scanf는 성공적으로 입력되면 1을 반환한다. x가 double형 변수이므로 scanf에서 변환문자 %ld를 사용하였다. 23 if (count == 0) { /* 읽어들인 데이터가 없는 경우 */ 24 printf(“no data entered.\n”); 25 exit(0); 26 } 27 avg = sum / count; 28 29 printf(“%5s%8s%8s%8s\n”, “count”, “minimum”, “maximum”, “average”); 30 printf(“%5d%8.1f%8.1f%8.3f\n”, count, min, max, avg); 31 } 예제 5.12 (계속) [해 설] output scanf는 성공적으로 입력되면 1을 반환한다. x가 double형 변수이므로 scanf에서 변환문자 %ld를 사용하였다. testdata란 file이 다음과 같이 한 줄로 구성되었다 하자. 70 65 11.6 -15 0.21e1 UNIX기게에서 컴파일/링크 후 동작시키는 모습 cc –o ex5-12 ex5-12.c ex5-12 < testdata 키보드에서 직접 입력시에는 데이터의 종료를 알려야 한다. DOS기계에서는 ctrl-Z, UNIX기계에서는 ctrl-D를 사용함. count minimum maximum average 5 -15.0 70.0 26.740
표준입력을 표준출력에 복사한다. 단 소문자는 대문자로 바꾼다. 1 /* File : ex5-13.c 2 다음 프로그램이 수행하는 일을 설명하시오. */ 3 #include <stdio.h> 4 int main(void) 5 { 6 int c; 7 while ((c = getchar()) != EOF) { 8 if (c >= ‘a’ && c <= ‘z’) /* (1) */ 9 c = c - ‘a’ + ‘A’; 10 putchar(c); 11 } 12 } 예제 5.13 [해 설] output 표준입력을 표준출력에 복사한다. 단 소문자는 대문자로 바꾼다. putchar와 getchar는 문자를 int에 저장하여 사용한다. file끝이 마치 문자인 것처럼 처리하게 할 수 있다. file끝(EOF)은 <stdio.h>에서 통상 –1로 정의된다. (1)은 if ((c >= ‘a’) && (c <= ‘z’))와 같은 의미이다. 위의 방법은 아스키나 엡시딕 등 코드와 무관하게 동작된다. 입력file이 다음과 같다고 하자. Hello, World! Welcome to SEOUL. HELLO, WORLD! WELCOME TO SEOUL.
예제 5.14 1 /* File : ex5-14.c 2 다음 프로그램이 수행하는 일을 설명하시오. */ 2 다음 프로그램이 수행하는 일을 설명하시오. */ 3 #include <stdio.h> 4 int main(void) 5 { 6 int c, blank_cnt = 0, letter_cnt = 0, nl_cnt = 0, other_cnt = 0; 7 8 while ((c = getchar()) != EOF) /* while 몸체에 { } 불필요 */ 9 if (c == ‘ ’ && c == ‘\t’) 10 blank_cnt++; 11 else if (c >= ‘a’ && c <= ‘z’ || c >= ‘A’ && c <= ‘Z’) 12 letter_cnt++; 13 else if (c == ‘\n’) 14 nl_cnt++; 15 else 16 other_cnt++; 17 printf(“\n%12s%12s%12s%12s”, 18 “blanks”, “letters”, “lines”, “others”, “total”); 19 printf(“\n\n%12d%12d%12d%12d%12d\n\n”, 20 blank_cnt, letter_cnt, nl_cnt, other_cnt, 21 blank_cnt + letter_cnt + nl_cnt + other_cnt); 22 } 예제 5.14
입력 자료로부터 공백, 영문자, 줄바꿈문자 및 기타 문자의 수를 세는 프로그램 본 원시 프로그램 file을 입력으로 다음같이 돌려보자 ex5-14 < ex5-14.c 예제 5.14(계 속) [해 설] output blanks letters lines others total 142 258 22 229 651
예제 5.15 1 /* File : ex5-15.c 2 임의 개의 자료를 읽어 들여 점수와 letter grade를 출력 */ 3 #include <stdio.h> 4 int main(void) 5 { 6 int points; 7 char let_gr; 8 printf(“POINTS LETTER_GRADE\n”); 9 printf(“ --------------------\n”); 10 while (scanf(“%d”, &points) == 1) { 11 switch (points / 10) { 12 case 10: 13 case 9: let_gr = ‘A’; break; 14 case 8: let_gr = ‘B’; break; 15 case 7: let_gr = ‘C’; break; 16 case 6: let_gr = ‘D’; break; 17 default: let_gr = ‘F’; 18 } 19 printf(“ %d %c\n”, points, let_gr); 20 } 21 } 예제 5.15
점수를 letter grade로 바꾸는 프로그램 입력 file(datafile)을 다음과 같다고 하자. 88 97 75 96 70 35 본 원시 프로그램 file을 입력으로 다음같이 돌려보자 ex5-15 < datafile 예제 5.15(계 속) [해 설] output POINTS LETTER_GRADE -------------------- 88 B 97 A 75 C 96 A 70 C 35 F