본문 바로가기
Programming/C Programming Modern Approach (K.N.K)

[KNK 정리] 5장: Selection Statements

by hyeyoo 2021. 8. 18.
※ 이 블로그의 글은 글쓴이가 공부하면서 정리하여 쓴 글입니다.
※ 최대한 내용을 검토하면서 글을 쓰지만 틀린 내용이 있을 수 있습니다.
※ 만약 틀린 부분이 있다면 댓글로 알려주세요.

요약/정리

C언어에는 몇가지의 statements가 있다. 이번 장에서는 selection statements를 다룬다.

- selection statements: if / switch 등 조건에 따라 분기하는 구문

- iteration statements: for, while, do-while 등 정해진 동작을 반복하는 구문

- jump statements: 코드를 점프하는 구문

- compound statement: 여러 개의 구문을 하나의 구문으로 만들기 위한 구문

- null statement: 아무 동작도 수행하지 않는 구문

logical expressions

우리는 4장에서 배웠듯 연산자를 통해서 다양한 expression을 만들 수 있다. 하지만 x + y와 같은 expression과 다르게, 참이냐 거짓이냐가 중요한 expression(logical expression)이 있다. 관계 연산자와 논리 연산자로 logical expression을 만들 수 있다. 쉬운 내용이므로 간단하게만 적겠다. 참고할 점은, 관계연산자와 논리연산자를 사용하여 만든 expression의 값은 항상 0 (거짓) 또는 1 (참)이 된다.

 

relational operators

a < b : a가 b보다 작다

a > b : a가 b보다 크다

a <= b : a가 b보다 작거나 같다

a >= b : a가 b보다 크거나 같다

 

주의: a < b < c 라는 expression은 C에서 의미가 없다.

a = 1, b = 3, c = 2라면 (a < b < c) -> ((1 < 3) < 2) -> ((1) < 2) -> 1 과 같이 예상했던 바와 다르게 계산이 된다.

equality operators

a == b : a와 b가 같다

logical operators

!expr: expr이 0이면 값이 1, expr이 non-zero이면 값이 0

expr1 && expr2: expr1과 expr2가 non-zero이면 값이 1, 그렇지 않다면 0

expr1 || expr2: expr1 또는 expr2가 non-zero라면 값이 1, 그렇지 않다면 0

 

short-circuit evaluation

아래 인용한 C89, C99 문서를 보면, local AND operator (&&)에 대하여 (logical OR operator에 대해서도 똑같이 명시되어있다.), 왼쪽에서 오른쪽 순서대로 evaluate됨이 보장되며, expr1 && expr2에서 expr1이 거짓인 경우에는 expr2가 evaluate되지 않는다고 나와있다. 당연한 말이라고 생각할 수 있다. 0 && expr2는 expr2가 무엇이든 간에 거짓이기 때문이다. 이러한 특징을 short-circuit evaluation이라고 한다. expr2에 side effect가 존재할 경우를 유의하여 작성해야 한다. short-circuit evaluation에 의해 expr2가 evaluate되지 않으면 side effect도 발생하지 않는다.

Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares equal to 0, the second operand is not evaluated.
ISO/IEC 9899:TC3, p.89

 

if statement

형식: if ( expression ) statement

expression이 non-zero일 때 statement를 실행한다. 

compound statements

형식: { statements }

compound statement를 사용하면 여러 개의 statement를 하나의 statement로 취급할 수 있다. 보통 if를 위의 형식이 아니라 if ( expression ) { statements } 라고 배우고, statement가 하나일 때는 중괄호를 생략할 수 있다고 배운다. 사실은 반대다. if문에는 하나의 statement를 compound statement로 대체한 것이다.

else clause

형식: if ( expression ) statement else statement

if statement에 else clause를 추가하면, expression이 거짓일 때 else 뒤의 statement가 실행된다.

cascaded if statements

프로그램을 작성하다보면 if와 else만으로는 부족한 상황이 생긴다. expression 하나가 아니라 여러개를 검사해야할 수도 있다. 그래서 프로그램을 작성하다보면 다음과 같은 형태로 작성할 수 있다.

 

if ( expression )

    statement

else if ( expression )

    statement

else if ( expression )

    statement

....

else

    statement

 

참고할 점은 C언어에 'else if'라는 statement는 없다. 'if ( expression ) statement else statement' 자체도 하나의 statement 이기 때문에, 이것을 else의 statement에 대입하면 if - else if - else if - ... - else 이러한 형태로 cascading을 할 수 있는 것이다.

dangling else

다음 if statement를 보자.

 

if ( expression ) // (1)

    if ( expression) // (2)

else // (3)

    statement

 

여기서 else (3)은 if (1), (2) 중 누구의 else인가? 들여쓰기 때문에 (1)이라고 생각할 수도 있지만, 들여쓰기는 사람을 위한 것이지 컴파일러에겐 중요하지 않다. 이럴 땐 가장 가까운 if (2)와 연결되는 else가 된다.

conditional expressions

형식: expr1 ? expr2 : expr3

expr1이 non-zero이면 위의 expression은 expr2의 값을 갖고, expr1이 거짓이면 expr3의 값을 갖는다. 이때 ?: 연산자는 conditional operator라고도 하고 ternary operator라고도 한다. 그리고 conditional expression 자체가 하나의 expression이므로, conditional expression은 얼마든지 중첩해서 사용할 수 있다.

boolean values

C89까지는 참과 거짓만을 나타낼 타입이 존재하지 않았다. C99부터 _Bool이라는 타입이 생겨서 0 또는 1이라는 값만 저장할 수 있게 되었다. 왜 이름이 bool이 아니라 _Bool인가 하면, C89와의 하위호환성을 위해서다. C89에서는 bool이라는 키워드가 존재하지 않았기 때문에 bool이 identifier가 될 수 있었다. 그럼 왜 _Bool은 되냐? C89에서 __, _[A-Z] 로 시작하는 identifier를 사용하지 않도록 했기 때문이다. _Bool 타입의 변수에는 non-zero 값을 대입할 경우 항상 1로 저장되며, 0을 대입하면 0이 저장된다. <stdbool.h>을 인클루드하면 bool, true, false를 사용할 수 있다. 

switch statement

형식 : switch ( expression ) {

    case constant-expression : statements

    ...

    case constant-expression : statements

    default : statements

}

switch 바로 옆에 괄호로 감싸진 expression을 controlling expression이라고 부른다. 이 controlling expression은 항상 integer type (char, int, short int, ... 등등) 그 다음에는 중괄호에 case와 default가 오고, 이에 해당하는 statements가 온다. 이때 case 다음에 오는 expression은 constant-expression, 즉 상수로만 이루어진 expression이어야 한다.

break statement

swich문에서 break는 switch문을 빠져나오기 위해 사용된다. switch문은 그 특성상 해당 case에 대한 statements를 모두 실행한 후에도 switch문을 빠져나오는 게 아니라, 다음 case에 대한 statements를 이어서 실행한다. case에 대한 statements를 수행한 후 switch문을 빠져나오게 하려면 statements의 마지막에 break를 넣어주어야 한다.

 

또한, case가 끝난 후 의도적으로 다음 case로 넘어가게 하려면 아래 코드처럼 그걸 명시적으로 표시해주는 것이 좋다.

switch (c) {
  case 1:
  case 2:
            ... Do some of the work ...
            /* FALLTHROUGH */
  case 17:
            ... Do something ...
            break;
  case 5:
  case 43:
            ... Do something else ...
            break;
}

jump table

책에는 없지만 switch문은 jump table을 통해 cascaded if statements보다 빠르게 구현된다. 이는 constant-expression에 대해서 어느 코드로 점프할지를 배열로 저장하는 것이다. 그러면 constant-expression 인덱스로 하는 배열(jump table)을 이용해서 한 번에 원하는 영역으로 점프할 수 있다. 그렇기 때문에 switch statement는 constant-expression이 다수 존재하고, 그 간격이 빽빽할 때 효율이 가장 높이 올라간다. 반대로 constant-expression간의 간격이 너무 듬성듬성하면 메모리 효율이 좋지 않아 컴파일러가 cascaded if statements로 변환할 수도 있다.

 

Exercises

나의 정신건강을 위해 연산자 우선순위와 결합 방향 표를 첨부한다.

1. The following program fragments illustrate the relational and equality operators. Show the output produced by each, assuming that i, j, and k are int variables.

 

(a) i = 2; j = 3; 

k = i * j == 6;

printf("%d", k);

답: 1

 

(b) i = 5; j = 10; k = 1;

printf("%d", k > i < j);

답: 1

(k > i < j) -> (k > i) < j -> 0 < j -> 1

 

(c) i = 3; j = 2; k = 1;

printf("%d", i < j == j < k);

답: 1

i < j == j < k -> 0 == j < k -> 0 == 0 -> 1

 

(d) i = 3; j = 4; k = 5;

printf("%d", i % j + i < k);

답: 0

i % j + i < k -> 3 + i < k -> 6 < k -> 0

 

2. The following program fragments illustrate the logical operators. Show the output produced by each, assuming that i, j, and k are int variables.

 

(a) i = 10; j = 5;

printf("%d", !i < j);

답: 1

!i < j -> 0 < j -> 1

 

(b) i = 2; j = 1;

printf("%d", !!i + !!j);

답: 2

!!i + !!j -> !0 + !0 -> 1 + 1 -> 2

 

(c) i = 5; j = 0; k = -5;

printf("%d", i && j || k); // logical AND가 OR보다 우선순위가 높다. 왜지? i || j && k였으면 헷갈렸을듯.

답: 1

i && j || k -> 0 || k -> 1

 

(d) i = 1; j = 2; k = 3;

printf('%d", i < j || k);

답: 1

i < j || k -> 1 || k -> 1

 

3. The following program fragments illustrate the short-circuit behavior of logical expressions. Show the output produced by each, assuming that i, j, and k are int variables.

여기서 참고할 점 : ||, &&은 표준상 left to right evaluation을 보장한다.

 

(a) i = 3; j = 4; k = 5;

printf("%d ", i < j || ++j < k); 

printf("%d %d %d", i, j, k);

답: 1 3 5 5

 

(b) i = 7; j = 8; k = 9;

printf("%d ", i - 7 && j++ < k);

printf("%d %d %d", i, j, k);

답: 0 7 9 9

 

(c) i = 7; j = 8; k = 9;

printf("%d ", (i = j) || (j = k));

printf("%d %d %d", i, j, k);

답: 1 8 9 9

 

(d) i = 1; j = 1; k = 1;

printf("%d ", ++i || ++j && ++k);

printf("%d %d %d", i, j, k);

답: 1 2 2 2

 

4. Write single expression whose value is either -1, 0, or +1, depending on whether i is less than, equal to, or greater than j, respectively.

답: (i < j ? -1 : (i > j ? 1 : 0))

 

5. Is the following if statement legal?

if (n >= 1 <= 10)

    printf("n is between 1 and 10\n");

If so, what does it do when n is equal to 0?

문법적으로 문제는 없다. n이 0이라면, expression은 ((0 >= 1) <= 10)이 된다. expression의 값 자체는 1이 되는데 별 의미가 없다.

 

6. Is the following if statement legal?

if (n == 1-10)

    printf("n is between 1 and 10\n");

If so, what does it do when n is equal to 5?

이것도 문법적으로 문제는 없다. 근데 1-10이면 n이 1~10이라는 게 아니라 n == -9이므로, n이 5라면 해당 expression은 거짓이 된다.

 

7. What does the following statement print if i has the value 17? What does it print if i has the value -17?

printf("%d", (i >= 0 ? i - i));

이건 그냥 절댓값을 출력하는 코드다. 두 경우 모두 17이 출력된다.

 

8. The Following if statement is unnecessarily complicated, Simplify it as much as possible (Hint: The entire statement can be replaced by single assignment.)

 

if (age >= 13)

    if (age <= 19)

        teenager = true;

    else

        teenager = false;

else if (age < 13)

    teenager = false;

 

답: teenager = (13 <= age && age <= 19);

 

9. Are the following if statements equivalent? If not, why not?

if (score >= 90)

    printf("A");

else if (score >= 80)

    printf("B");

else if (score >= 70)

    printf("C");

else if (score >= 60)

    printf("D");

else

    printf("F");

 

if (score < 60)

    printf("F");

else if (score < 70)

    printf("D");

else if (score < 80)

    printf("C");

else if (score < 90)

    printf("B");

else

    printf("A"); 

 

답: equivalent

 

10. What output does the following program fragment produce? (Assume that i is an integer variable.)

i = 1;

switch (i % 3) {

    case 0: printf("zero");

    case 1: printf("one");

    case 2: printf("two");

}

답: onetwo

 

11. The following table shows telephone area codes in the state of Georgia along with the largest city in each area: Area code   Major city

229 Albany

404 Atlanta

470 Atlanta

478 Macon

678 Atlanta

706 Columbus

762 Columbus

770 Atlanta

912 Savannah

 

Write a switch statement whose controlling expression is the variable area_code. If the value of area_code is in the table, the switch statement will print the corresponding city name. Otherwise, the switch statement will display the message "Area code not recognized". Use the techniques discussed in Section 5.3 to make the switch statement as simple as possible.

답: 

switch (area_code) {
    case 229:
        printf("Albany\n");
        break;
    case 404:
    case 470:
    case 678:
    case 770:
        printf("Atlanta\n");
        break;
    case 478:
        printf("Macon\n");
        break;
    case 706:
    case 762:
        printf("Columbus\n");
        break;
    case 912:
        printf("Savannah\n");
    default:
        printf("Area code not recognized\n");       
}

Programming Projects

I. Write a program that calculates how many digits a number contains:

Enter a number: 374

The number 374 has 3 digits

 

You may assume that the number has no more than four digits. Hint: Use if statements to test the number. For example, if the number is between 0 and 9. it has one digit. If the num¬ ber is between 10 and 99. it has two digits.

 

#include <stdio.h>

int main(void)
{
    int number, n_digits;
    
    printf("Enter a number: ");
    scanf("%d", &number);
    
    if (number < 10)
        n_digits = 1;
    else if (number < 100)
        n_digits = 2;
    else if (number < 1000)
        n_digits = 3;
    else
        n_digits = 4;
        
    printf("The number %d has %d digits\n", number, n_digits);
    
    return 0;
        
}

2. Write a program that asks the user for a 24-hour time, then displays the lime in 12-hour form:

Enter a 24-hour time: 21:11

Equivalent 12-hour time: 9:11 PM

 

Be careful not to display 12:00 as 0:00.

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    int hour, min;
    bool isPM;
    
    printf("Enter a 24-hour time: ");
    scanf("%d:%d", &hour, &min);
    
    isPM = hour >= 12;
    if (hour >= 12)
        hour -= 12;
        
    printf("Equivalent 12-hour time: %2d:%2d %s", hour, min, (isPM ? "PM" : "AM"));
    
    return 0;
}

4. Here's a  simplified version of the Beaufort scale, which is used to estimate wind force:

 

Speed (knots) / Description

less than 1 / Calm

1-3 / Light air

4-27: Breeze

28 - 47: Gale

48 - 63: Storm

Above 63: Hurricane

 

Write a program that asks the user to enter a wind speed (in knots), then displays the corresponding description

#include <stdio.h>

int main(void)
{
    int speed;
    const char *desc;
    
    printf("input speed: ");
    scanf("%d", &speed);
	
    if (speed < 1)
    	desc = "Calm";
    else if (speed <= 3)
        desc = "Light air";
    else if (speed <= 27)
        desc = "Breeze";
    else if (speed <= 47)
        desc = "Gale";
    else if (speed <= 63)
        desc = "Storm";
    else
        desc = "Hurricane";
    
    printf("Description: %s", desc);
    
    return 0;
}

5. In one state, single residents are subject to the following income tax:
Income            Amount of tax
Not over $750     1% of income
$750-$2,250       $7.50   plus 2% of amount over $750
$2,250-$3,750     $37.50  plus 3% of amount over $2,250
$3,750-$5,250     $82.50  plus 4% of amount over $3,750
$5,250-$7,000     $142.50 plus 5% of amount over $5,250
Over $7,000       $230.00 plus 6% of amount over $7,000
Write a program that asks the user to enter the amount of taxable
income, then displays the tax due.

#include <stdio.h>

int main(void)
{
    float income, tax;
    
    printf("input your income: ");
    scanf("%f", &income);
    
    if (income <= 750.00f) {
        tax = 0.01f * income;
    } else if (income <= 2250.00f) {
        tax = 7.50f + (income - 750.00f) * 0.02f;
    } else if (income <= 3750.00f) {
        tax = 37.50f + (income - 2250.00f) * 0.03f;
    } else if (income <= 5250.00f) {
        tax = 82.50f + (income - 3750.00f) * 0.04f;
    } else if (income <= 7000) {
        tax = 142.50f + (income - 5250.00f) * 0.05f;
    } else {
        tax = 230.00f + (income - 7000.00f) * 0.06f;
    }
    
    printf("your tax is ...: %.2f", tax);
    
    return 0;
}

6. Modify the upc.c program of Section 4.1 so that it checks twhether a UPC is valid. After the user enters a UPC, the program will display either VALID or NOT VALID.

#include <stdio.h>

int main(void)
{
	int d, i1, i2, i3, i4, i5, j1, j2, j3, j4, j5, check;
	int first_sum, second_sum, total;

	printf("Enter a UPC: ");
	scanf("%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d",
	        &d, &i1, &i2, &i3, &i4, &i5, &j1, &j2, &j3, &j4, &j5, &check);

	first_sum = d + i2 + i4 + j1 + j3 + j5;
	second_sum = i1 + i3 + i5 + j2 + j4;
	total = 3 * first_sum + second_sum;

	if (check == 9 - ((total - 1) % 10)) {
		printf("VALID\n");
	} else {
		printf("NOT VALID\n");
	}

	return 0;
}

7. Write a program that finds the largest and smallest of four integers entered by the user: 

Enter four integers: 21 43 10 35

Largest: 43

Smallest: 10

 

Use as few if statements as possible. Hint: Four if statements are sufficient.

#include <stdio.h>

int main(void)
{
    int max, min, max1, max2, min1, min2, a, b, c, d;
    
    printf("Enter four integers: ");
    
    scanf("%d%d%d%d", &a, &b, &c, &d);
    
    min1 = b;
    max1 = a;
    if (a < b) {
        min1 = a;
        max1 = b;
    }
    
    min2 = d;
    max2 = c;
    if (c < d) {
        min2 = c;
        max2 = d;   
    }
    
    max = max1;
    if (max1 < max2) {
        max = max2;
    }
    
    min = min2;
    if (min1 < min2) {
        min = min1;
    }
    
    printf("Largest: %d\n", max);
    printf("Smallest: %d\n", min);
    
    return 0;
}

5. The following table shows the daily flights from one city to another:
Departure time    Arrival time
8:00 a.m.        10:16 a.m.
9:43 a.m.        11:52 a.m.
11:19 a.m.         1:31 p.m.
12:47 p.m.         3:00 p.m.
2:00 p.m.         4:08 p.m.
3:45 p.m.         5:55 p.m.
7:00 p.m.         9:20 p.m.
9:45 p.m.        11:58 p.m.

Write a program that asks the user to enter a time (expressed in hours
and minutes, using the 24-hour clock). The program then displays the
departure and arrival times for the flight whose departure time is
closest to that entered by the user:
Enter a 24-hour time: 13:15
Closest departure time is 12:47 p.m., arriving at 3:00 p.m.

Hint: convert the input into a time expressed in minutes since midnight,
and compare it to the departure times, also expressed in minutes since
midnight. For example, 13:15 is 13 x 60 + 15 = 795 minutes since midnight,
which is closer to 12:47 p.m. (767 minutes since midnight) than to any
of the other departure times.

#include <stdio.h>

#define abs(x) ((x) > 0 ? (x) : -(x))

int main(void)
{
    const char *am_pm;
    int hour, minute, ans_time = 0, ans_diff = 0, ans_arrive;
    int t1 = 8 * 60,
        t2 = 9 * 60 + 43,
        t3 = 11 * 60 + 19,
        t4 = 12 * 60 + 47,
        t5 = 14 * 60,
        t6 = 15 * 60 + 45,
        t7 = 19 * 60,
        t8 = 21 * 60 + 45;
    
    printf("Enter a 24-hour time: ");
    scanf("%d:%d", &hour, &minute);
    minute += hour * 60;
    
    ans_diff = abs(minute - t1);
    ans_time = t1;
    ans_arrive = 10 * 60 + 16;
    
    if (abs(minute - t2) < ans_diff) {
        ans_time = t2;
        ans_diff = abs(minute - t2);
        ans_arrive = 11 * 60 + 52;
    }
    
    if (abs(minute - t3) < ans_diff) {
        ans_time = t3;
        ans_diff = abs(minute - t3);
        ans_arrive = 13 * 60 + 31;
    }
    
    if (abs(minute - t4) < ans_diff) {
        ans_time = t4;
        ans_diff = abs(minute - t4);
        ans_arrive = 15 * 60;
    }
    
    if (abs(minute - t5) < ans_diff) {
        ans_time = t5;
        ans_diff = abs(minute - t5);
        ans_arrive = 16 * 60 + 8;
    }
    
    if (abs(minute - t6) < ans_diff) {
        ans_time = t6;
        ans_diff = abs(minute - t6);
        ans_arrive = 17 * 60 + 55;
    }
    
    if (abs(minute - t7) < ans_diff) {
        ans_time = t7;
        ans_diff = abs(minute - t7);
        ans_arrive = 21 * 60 + 20;
    }
    
    if (abs(minute - t8) < ans_diff) {
        ans_time = t8;
        ans_diff = abs(minute - t8);
        ans_arrive = 11 * 60 + 58;
    }
    
    hour = ans_time / 60;
    minute = ans_time % 60;
    if (hour >= 12) {
        hour -= 12;
        am_pm = "p.m.";
    } else {
        am_pm = "a.m.";
    }
    
    printf("Closest departure time is: %d:%.2d %s\n", hour == 0 ? 12 : hour, minute, am_pm);
    
    hour = ans_arrive / 60;
    minute = ans_arrive % 60;
    if (hour > 12) {
        hour -= 12;
        am_pm = "p.m.";
    } else {
        am_pm = "a.m.";
    }
    
    printf(", arriving at %d:%.2d %s\n", hour == 0 ? 12 : hour, minute, am_pm);
    
    return 0;
}

9. Write a program that prompts the user to enter two dates and then indicates which date comes earler on the calendar:

Enter first date (mm/dd/yy): 3/6/08
Enter second date (mm/dd/yy): 5/17/07
5/17/07 is earler than 3/6/08

#include <stdio.h>


int main(void)
{
    int month1, month2, day1, day2, year1, year2;
    
    printf("Enter first date (mm/dd/yy): ");
    scanf("%d/%d/%d", &month1, &day1, &year1);
    
    printf("Enter second date (mm/dd/yy): ");
    scanf("%d/%d/%d", &month2, &day2, &year2);
    
    if (year1 == year2) {
        if (month1 == month2) {
            if (day1 == day2) {
                printf("%d/%d/%02d and %d/%d/%02d are same.", month1, day1, year1, month2, day2, year2);
            } else if (day1 < day2) {
                printf("%d/%d/%02d is earler than %d/%d/%02d", month1, day1, year1, month2, day2, year2);
            } else {
                printf("%d/%d/%02d is earler than %d/%d/%02d", month2, day2, year2, month1, day1, year1);
            }
        } else if (month1 < month2) {
            printf("%d/%d/%02d is earler than %d/%d/%02d", month1, day1, year1, month2, day2, year2);
        } else {
            printf("%d/%d/%02d is earler than %d/%d/%02d", month2, day2, year2, month1, day1, year1);
        }
    } else if (year1 < year2) {
        printf("%d/%d/%02d is earler than %d/%d/%02d", month1, day1, year1, month2, day2, year2);
    } else {
        printf("%d/%d/%02d is earler than %d/%d/%02d", month2, day2, year2, month1, day1, year1);
    }
    
    return 0;
}

10. Using the switch statement, write a program that converts a numerical grade into a letter grade:
Enter numerical grade: 84
Letter grade: B

Use the following grading scale A = 90-100, B = 80-89, C = 70-79, D = 60-69, F = 0-59. Print an error message if the grade is larger than 100 or less than 0. Hint: Break the grade into two digits, then use switch statement to test the ten's digit.

 

#include <stdio.h>


int main(void)
{
    int grade, first_digit, second_digit;
    char letter;
    
    printf("Enter numerical grade: ");
    scanf("%d", &grade);
        
    first_digit = grade / 10;
    second_digit = grade % 10;
    
    switch (first_digit) {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
            letter = 'F';
            break;
        case 6:
            letter = 'D';
            break;
        case 7:
            letter = 'C';
            break;
        case 8:
            letter = 'B';
            break;
        case 10:
            switch (second_digit) {
                case 0:
                    break;
                default:
                    printf("Wrong grade!\n");
                    return 0;
            }
            /* FALL THROUGH */
        case 9:
            letter = 'A';
            break;
        default:
            printf("Wrong grade!\n");
            return 0;
    }
    
    printf("Letter grade: %c", letter);

    return 0;
}

11. Write a program that asks the user for a two-digit number, then prints the English word for the number:
Enter a two-digit number: 45
You entered the number forty-five.

Hint: Break the number into two digits. Use one switch statement to
print the word for the first digit ("twenty," "thirty," and so forth).
Use a second switch statement to print the word for the second digit.
Don't forget that the numbers between 11 and 19 require special
treatment.

#include <stdio.h>


int main(void)
{
    int number, first_digit, second_digit;
    
    printf("Enter a two-digit number: ");
    scanf("%d", &number);
    
    first_digit = number / 10;
    second_digit = number % 10;
    
    printf("You entered the number ");
    
    /* 11-19 are special */
    switch (number) {
        case 10:
            printf("ten");
            return 0;
        case 11:
            printf("eleven");
            return 0;
        case 13:
            printf("twelve");
            return 0;
        case 14:
            printf("thirteen");
            return 0;
        case 15:
            printf("fourteen");
            return 0;
        case 16:
            printf("fifteen");
            return 0;
        case 17:
            printf("sixteen");
            return 0;
        case 18:
            printf("seventeen");
            return 0;
        case 19:
            printf("nineteen");
            return 0;
    }
    
    switch (first_digit) {
        case 2:
            printf("twenty");
            break;
        case 3:
            printf("thirty");
            break;
        case 4:
            printf("fourty");
            break;
        case 5:
            printf("fifty");
            break;
        case 6:
            printf("sixty");
            break;
        case 7:
            printf("seventy");
            break;
        case 8:
            printf("eighty");
            break;
        case 9:
            printf("ninety");
            break;
    }
    
    printf("-");
    
    switch (second_digit) {
        case 0:
            printf("zero");
            break;
        case 1:
            printf("one");
            break;
        case 2:
            printf("two");
            break;
        case 3:
            printf("three");
            break;
        case 4:
            printf("four");
            break;
        case 5:
            printf("five");
            break;
        case 6:
            printf("six");
            break;
        case 7:
            printf("seven");
            break;
        case 8:
            printf("eight");
            break;
        case 9:
            printf("nine");
    }
    
    return 0;
}

댓글