Programmers are not to be measured by their ingenuity and their logic but by the completeness of their case analysis
operator에 비하면 statement의 종류는 꽤 적음.
앞에서 다룬 return statement와 expression statement 이외에 다른 statement는 크게 세 종류로 나눌 수 있다.
Selection statements: if and switch statements
Iteration statements: while, do, for statements
Jump statemets: break, continue, goto, return도 여기에 속함.
compound statement: 여러개의 statement를 묶어서 하나의 statement로 만듬
null statment: no action
이 장에서는 selection, compound statement를 다룸
5.1 Logical Expressions
C는 논리 연산자가 boolean type을 반환하는 것이 아니라 정수를 반환한다. 0(false) 또는 1(true)
relational operators: <, >, <=, >=
1 < 2.5의 값은 1
6 < 4의 값은 0
relational operators의 우선순위는 arithmetic operators(+-/*&)보다 낮다.
equality operators: ==, !=
logical opeators: !, &&, ||
!
logical negation
&&
logical and
||
logical or
short-circuit evaluation: &&와 ||의 경우 첫번째 operand(피연산자)만으로 이미 값을 알 수 있는 경우, 두번째 operand는 처리하지 않는다.
ex) (i != 0) && (j / i > 0);에서 i = 0이라면, 첫번째 operand의 값이 0이므로 이 statement의 값은 뒷 operand에 상관 없이 0이 된다. 그러므로 뒷 operand를 처리하지 않고 0이 된다. 만약 뒷 operand까지 처리했다면 division by zero로 에러가 발생했을 것이다.
! 연산자는 unary plus, unary minus(+-기호)와 우선순위가 같다. &&와 ||는 relational, equality 연산자보다 우선순위가 낮다.
5.2 The if Statement
형식: if (expression) statement
if statement가 실행되면, 괄호 안의 expression의 값이 0인지 아닌지를 따져서 0이 아니면(nonzero) 괄호 뒤에 있는 statement를 실행한다.
compound statements
형식: { statements }
중괄호 안에 여러 개의 statements를 넣어 주면, 컴파일러는 그것을 하나의 statement로 인식하게 된다.
loop이나 C가 한 개의 statement를 요구하지만 우리가 여러개를 넣고 싶을 때 사용된다.
else를 사용 하는 경우
if ( expression ) statement else statement
cascaded if statements
if ( expression )
statement
else if ( expression )
statement
...
else if( expression )
statement
else
statement
#include <stdio.h>
int main()
{
float commission, value;
printf("Enter value of trade: ");
scanf("%f", &value);
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;
}
The "Dangling else" problem
다중 if 문이 있을 때, else는 가장 가까운 if문과 짝을 이루게 된다. 파이썬처럼 indentation을 이용해더 먼 if문과 짝을 이루게 할 수 없다. 만약 바깥쪽의 if문과 else를 매치시키려면, 중괄호를 사용해 안쪽의 if문을 compound statement로 묶어야 함.
Conditional expressions
lvalue = expr 1 ? expr 2 : expr 3
if expr1 then {lvalue = expr2} else {lvalue = expr3}과 동일한 의미.
boolean values
오랫동안 C에는 적합한 boolean type이 없었다. C99에 이르러 _Bool 이란 type이 제공됨. 이 type으로 선언된 변수는 0 또는 1만 값으로 가질 수 있다.
_Bool flag;
flag = -1243; // 어떠한 nonzero value를 입력하면, flag의 값은 1로 설정된다.
또는 <stdbool.h> 를 include해서,
bool flag; // _Bool flag;와 같음
flag = true; flag = false;
5.3 The switch Statement
cascaded if statement보다 읽기 편하고, case가 많다면 if보다 빠른 경우가 많다
switch ( expression ) {
case constant-expression : statements
...
case constant-expression : statements
default : statements
}
controlling expression : switch 다음에는 반드시 괄호 안에 들어있는 정수 expression이 와야 함. 소수나 문자열은 올 수 없음
case labels: 각각의 case는 case constant-expression으로 시작해야 함.
constant-expression에는 5 가능, 5 + 10 가능, 그러나 n + 10 불가능(n이 상수인 macro가 아닌 이상). 정수 또는 문자 한개여야 함.
case 다음엔 하나의 constant expression만 올 수 있지만,
case 5: case 4: case 3:
printf("passing");
break;
같은 형태로 여러 개의 case를 동시에 처리할 수 있다.
하나의 case를 범위로 지정하는 것은 불가능하다.
case뒤 statement 다음에 break;를 써주지 않으면 그 다음 case의 statement도 순차적으로 실행된다.
만약 의도적으로 case 뒤에 break;를 빼먹은 거라면 그 의도를 명확히 표시해 주는것이 좋다. 왜냐하면 다른 누군가가 그걸 보고 실수라고 생각해서 break;를 추가할 수도 있기 때문이다.
#pragma warning(disable:4996)
#include <stdio.h>
int main()
{
int month, day, year;
printf("Enter date (mm/dd/yy): ");
scanf("%d/%d/%d", &month, &day, &year);
printf("Dated this %d", day);
switch (day) {
case 1: case 21: case 31:
printf("st"); break;
case 2: case 22:
printf("nd"); break;
case 3: case 23:
printf("rd"); break;
default: printf("th"); break;
}
printf(" day of ");
switch (month) {
case 1: printf("January");break;
case 2: printf("February");break;
case 3: printf("March");break;
case 4: printf("April");break;
case 5: printf("May");break;
case 6: printf("June");break;
case 7: printf("July");break;
case 8: printf("August");break;
case 9: printf("September"); break;
case 10: printf("October");break;
case 11: printf("November");break;
case 12: printf("December");break;
}
printf(", 20%.2d.\n", year);
return 0;
}
exercieses
4번 i<j이면 -1, i=j이면 0, i>j면 1을 반환하는 single expression
(i>j) - (i<j)
8번 변수에 true or false값을 하나의 assignment로 집어넣기
#include <stdio.h>
#include <stdbool.h>
int main()
{
int age;
bool teenager;
teenager = (age >= 13 && age <= 19);
}
11번 Area code
switch (area_code) {
case 229:
printf("Albany");break;
case 404: case 470: case 678: case 770:
printf("Atlanta"); break;
case 478:
printf("Macon");break;
case 706: case 762:
printf("Columbus");break;
case 912:
printf("Savannah"); break;
default:
printf("Area code not recognized");
}
projects
1번
#pragma warning(disable:4996)
#include <stdio.h>
int main()
{
int i, j;
printf("Enter a number: ");
scanf("%d", &i);
if (i >= 0 && i <= 9)
j = 1;
else if (i >= 10 && i <= 99)
j = 2;
else if (i >= 100 && i <= 999)
j = 3;
else if (i >= 1000 && i <= 9999)
j = 4;
else
{
printf("Invalid input.\n");
exit(1);
}
printf("The number %d has %d digits.\n", i, j);
}
2번
#pragma warning(disable:4996)
#include <stdio.h>
int main()
{
int h, m;
printf("Enter a 24-hour time: ");
scanf("%d:%d", &h, &m);
printf("Equivalent 12-hour time: ");
if (h == 0)
printf("12:%.2d AM\n", m);
else if (0 < h && h <= 11)
printf("%d:%.2d AM\n", h, m);
else if
(13 <= h && h <= 23)
printf("%d:%.2d PM\n", h - 12, m);
else // h = 12
printf("%d:%.2d PM\n", h, m);
return 0;
}
3번
#pragma warning(disable:4996)
#include <stdio.h>
int main()
{
float commission, price, value;
int shares;
float commission_rival;
printf("Enter the number of shares: ");
scanf("%d", &shares);
printf("Enter the price per share: ");
scanf("%f", &price);
value = shares * price;
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;
// case of rival's commission
if (shares < 2000)
commission_rival = 33.00f + .03f * shares;
else
commission_rival = 33.00f + .02f * shares;
printf("Commission: %.2f\n", commission);
printf("Commission of rival: %.2f\n", commission_rival);
return 0;
}
4번 바람의 세기
#pragma warning(disable:4996)
#include <stdio.h>
int main()
{
int speed;
printf("Enter a wind speed(in knots, int form): ");
scanf("%d", &speed);
if (speed > 63)
printf("Hurricane");
else if (speed >= 48)
printf("Storm");
else if (speed >= 28)
printf("Gale");
else if (speed >= 4)
printf("Breeze");
else if (speed >= 1)
printf("Light air");
else
printf("Calm");
printf("\n");
return 0;
}
5번 소득세 문제
#pragma warning(disable:4996)
#include <stdio.h>
int main()
{
float income, tax;
printf("Enter the amount of taxable income: ");
scanf("%f", &income);
if (income <= 750)
tax = .01f * income;
else if (income <= 2250)
tax = 7.50f + .02f * (income - 750);
else if (income <= 3750)
tax = 37.50f + .03f * (income - 2250);
else if (income <= 5250)
tax = 82.50f + .04f * (income - 3750);
else if (income <= 7000)
tax = 142.50f + .05f * (income - 5250);
else
tax = 230.00f + .06f * (income - 7000);
printf("You have to pay $ %.2f for your income tax.\n", tax);