모든 루프는 controlling expression이 있어야 한다(switch문 뒤에 오는 바로 그것).
loop이 실행될 때마다, controlling expression이 실행된다. 그리고 그 expression이 true(nonzero)라면, loop이 계속해서 실행된다.
loop 실행 - > controlling expression 실행 -> zero? or nonzero? -> nonzero면 loop 다시 실행
iteration statements는 세 가지: while, do, for
while은 body가 실행되기 전에 controlling expression을 테스트
do는 body가 실행된 후에 controlling expression을 테스트
for는 증가하거나 감소하는 counting variable(index?)를 가지고 루프 돌리기에 적합
break, continue, goto
break: loop에서 뛰쳐 나와서 loop 다음의 statement로 이동
continue: loop interation의 나머지 부분을 생략
goto: 함수 내의 아무 statement로 점프
null statement는 body가 비어 있는 loop를 만들 수 있다.
6.1 The while Statement
C에서 가장 단순하면서 가장 기초적인 loop 문.
while ( expression ) statement
while (i < n) /* controlling expression */
i = i * 2; /* loop body */
loop body는 single statement여야 한다. 여러 개의 statements를 원한다면 중괄호로 묶어 하나의 compound statement로 만들면 된다.
- while loop이 종료될 때, controlling expression의 값은 false이다.
- loop body는 단 한번도 실행되지 않을 수도 있다.
Infinite Loops: controlling expression의 값이 항상 nonzero여서 무한히 실행되는 loop
while (1)
로 시작하는 loop는 control을 loop 바깥으로 이동시키는 statement(break, goto, return)이나 프로그램을 종료시키는 함수가 들어있지 않으면 무한히 loop을 실행한다.
scanf("%d", &n);
while (n != 0) {
sum += n;
scanf("%d", &n);
}
loop문을 사용할 때, 위에서 scanf문을 두번 쓴 것처럼 같이 동일한 statements를 두 번 써야만 하는 경우가 종종 있다.
6.2 The do Statement
do statement while ( expression ) ;
do 문은 while문과 거의 유사하다. 단 차이는 controlling expression을 테스트하기 전에 body를 먼저 한번 실행한다는 것이다. 그러므로 controlling expression이 false더라도 body는 최소 한 번은 실행된다.
6.3 The for Statement
for ( expr1 ; expr2 ; expr3 ) statement
몇몇 예외적인 경우를 제외하면, for loop는 다음과 같은 형태로 while loop으로 표현할 수 있다.
expr1;
while ( expr 2 ) {
statement
expr3 ;
}
expr1은 초기화 단계로 단 한번만 수행된다.
expr2는 control expression으로 그 값이 nonzero면 계속 진행하고, 아니면 loop을 종료한다.
expr3은 loop이 한 바퀴 돌 떄마다 수행된다.
for statement idioms
for (i = 0; i < n; i++) -> counting up from 0 to n-1
for (i = 1; i <= n; i++) -> counting up form 1 to n
for (i = n; i >= 0; i--) -> counting down from n-1 to 0
for (i = n; i > 0; i--) -> counting down from n to 1
for(;;) : infinite loop
for(; i > 0;) : disguised while loop
comma expression
expr1, expr2
C에서 하나의 expression을 요구하지만, 두개 이상의 expression을 사용하고 싶다면, expression들을 콤마로 구분해서 사용하면 된다. 가장 마지막에 있는 expression의 값이 전체 expression의 value가 되며, 그 이전의 expression은 side-effect가 있어야만 존재할 가치가 있다.
sum = 0;
for (i=1; i <= N; i++)
sum += i;
->
for (sum = 0, i = 1; i <= N; i++)
sum += i;
6.4 Exiting from a Loop
while, for 문에서는 loop body 전에 loop 종료가 가능하고, do 문에서는 loop body 후에 종료가 가능하다.
만약 중간에 loop을 끝내고 싶다면? break statement를 쓰자.
continue statement는 loop 전체를 종료하지 않고 지금 돌고 있는 loop의 나머지 부분만 스킵할 수 있다.
goto statement는 하나의 statement에서 다른 statement로 점프하게 해 준다. (거의 사용되지 않음)
break, continue, return으로 대부분의 goto문을 대체할 수 있지만, goto문이 쓰일 수 있는 하나의 예시는 loop 안에 있는 switch문 안에서 loop를 끝내는 경우이다(break를 쓰면 switch 만 빠져나옴)
#pragma warning(disable:4996)
#include <stdio.h>
/* Balances a Checkbook */
int main(void)
{
int cmd;
float balance = 0.0f, credit, debit;
printf("*** ACME checkbook-balancing program ***\n");
printf("Commands: 0=clear, 1=credit, 2=debit, ");
printf("3=balance, 4=exit\n\n");
for (;;) {
printf("Enter command: ");
scanf("%d", &cmd);
switch (cmd) {
case 0:
balance = 0.0f;
break;
case 1:
printf("Enter amount of credit: ");
scanf("%f", &credit);
balance += credit;
break;
case 2:
printf("Enter amount of debit: ");
scanf("%f", &debit);
balance -= debit;
break;
case 3:
printf("Current balance: $%.2f\n", balance);
break;
case 4:
return 0;
default:
printf("Commands: 0=clear, 1=credit, 2=debit, ");
printf("3=balance, 4=exit\n\n");
break;
}
}
}
6.5 The Null Statement
statement can be null.
다음 line은 세개의 statements로 구성되어 있다.
i = 0; ; j = 1;
an assignment to i, a null statement, an assignment to j.
가장 중요한 용도는, for 문 뒤에 붙이는 것이다.
for (d = 2; d < n && n % d != 0; d++);
for 문 뒤에 ;를 붙인 것에 주목하자.
#pragma warning(disable:4996)
#include <stdio.h>
int main(void)
{
int d, n;
printf("input n: ");
scanf("%d", &n);
for (d = 2; d < n && n%d != 0; d++);
if (d < n)
printf("%d is divisible by %d\n", n, d);
else
printf("%d is a prime number.\n", n);
}
exercises
4번
(a) for (i=0; i<10; i++)
(b) for (i=0; i<10; ++i)
(c) for (i=0; i++<10;)
중 다른 하나는 (c). loop body가 실행되기 전에 i가 1 증가하기 때문이다.
6번
for (int i = 1; i <= 128; i *= 2)
printf("%d ", i);
12번 조금 더 효율적으로 소수 구하기(n의 sqrt까지만 for 문 돌리기)
#pragma warning(disable:4996)
#include <stdio.h>
int main(void)
{
int d, n;
printf("input value of n: ");
scanf("%d", &n);
for (d = 2; d*d < n; d++)
if (n % d == 0)
{
printf("%d is divisible by %d.\n", n, d);
return 0;
}
printf("%d is a prime number.\n", n);
}
Projects
1번
#pragma warning(disable:4996)
#include <stdio.h>
int main(void)
{
float max, n;
n = 1, max = -1;
while (n > 0) {
printf("Enter a number: ");
scanf("%f", &n);
if (n > max)
max = n;
}
if (max >= 0)
printf("The largest number entered was %.2f\n", max);
else
printf("There is no nonnegative number entered.\n");
return 0;
}
2번 computing GCD(greatest common divisor)
#pragma warning(disable:4996)
#include <stdio.h>
int main(void)
{
int m, n, temp;
printf("Enter two integers: ");
scanf("%d %d", &m, &n);
for (; n > 0; temp = m%n, m = n, n = temp);
printf("Greatest common divisor: %d\n", m);
return 0;
}
3번 분수의 약분 - 분자와 분모의 최대공약수를 이용.
#pragma warning(disable:4996)
#include <stdio.h>
int main(void)
{
int m, n, temp, a, b;
printf("Enter a fraction: ");
scanf("%d/%d", &m, &n);
a = m, b = n;
for (; n > 0; temp = m%n, m = n, n = temp);
printf("Greatest common divisor: %d/%d\n", a/m, b/m);
return 0;
}
4번
#pragma warning(disable:4996)
#include <stdio.h>
int main()
{
float commission, value;
for (;;) {
printf("Enter value of trade: ");
scanf("%f", &value);
if (value == 0)
break;
if (value < 2500.00f)
commission = 30.00f + .017f * value;
else if (value < 6250.00f)
commission = 56.00f + .0066f * value;
else if (value < 20000.00f)
commission = 76.00f + .0034f * value;
else if (value < 50000.00f)
commission = 100.00f + .0022f * value;
else if (value < 500000.00f)
commission = 155.00f + .0011f * value;
else
commission = 255.00f + .0009f * value;
if (commission < 39.00f)
commission = 39.00f;
printf("Comission: %.2f\n", commission);
}
return 0;
}
5번
#pragma warning(disable:4996)
#include <stdio.h>
int main()
{
int i;
printf("Enter a number: ");
scanf("%d", &i);
printf("Reversed number is ");
do{
printf("%d", i % 10);
i /= 10;
} while (i > 0);
printf("\n");
return 0;
}
6번 even squares
#pragma warning(disable:4996)
#include <stdio.h>
int main()
{
int i, n;
printf("Enter a number: ");
scanf("%d", &n);
for (i = 2; i * i <= n; i+=2)
printf("%d\n", i*i);
return 0;
}
7번
// loop body를 for문의 괄호 안에 집어넣으려면, 기존 expr3 앞에다 집어넣기
#pragma warning(disable:4996)
#include <stdio.h>
int main(void)
{
int i, n, odd, square;
printf("This program prints a table of squares.\n");
printf("Enter number of entries in table: ");
scanf("%d", &n);
for (i = 1, odd = 3, square = 1; i <= n; ++i, square += odd, odd += 2) {
printf("%10d%10d\n", i, square);
}
return 0;
}
8번 그 달이 며칠인지와 1일이 어떤 요일인지 입력받아 달력 만들기
#pragma warning(disable:4996)
#include <stdio.h>
int main(void)
{
int i, n, start;
printf("Enter number of days in month: ");
scanf("%d", &n);
printf("Enter starting day of the week (1=Sun, 7=Sat): ");
scanf("%d", &start);
printf("\n Sun Mon Tue Wed Thu Fri Sat\n");
for (i = 1; i < start; i++) // prints empty space before 1st
printf(" ");
for (i = 1; i <= n; i++)
{
printf("%4d", i);
if ((i + start - 1) % 7 == 0)printf("\n");
}
printf("\n\n");
return 0;
}
9번 chapter 2 project 8 monthly payment를 for문으로 표현하기
#pragma warning(disable:4996)
#include <stdio.h>
int main(void)
{
float total, ir, monthly;
int m;// number of payments before calculating balance remaining