C의 두드러지는 특징은 'expression(값을 계산하는 식)'을 statement보다 강조하는 것.
expression은 주로 표현식, statement는 문장으로 번역되는 것 같다.
가장 단순한 expression은, 변수와 상수.
operator : 연산자(덧셈, 뺄셈)
operand : 피연산자. 연산 당하는 수들
C는 흔치 않을 정도로 풍부한 operator collection을 가지고 있음
그중 가장 기본적인 것들
- arithmetic operators(addition, subtraction, multiplication, division)
- relational operators to perform comparisons
- logical operators to build conditions
이 장에서는 C의 가장 근본적인 operator들을 다룸.
arithmetic, assignment, increment and decrement operators.
precedence(우선순위), associativity(결합)
how C expressions are evaluated
expression statement(allows any expression to serve as a statement)
4.1 Arithmetic Operators
Unary |
Binary |
|
+ unary plus - unary minus |
Additive |
Multiplicative |
+ addition - subtraction |
* multiplication / division % remainder |
unary operators require one operand; inary operators require two operand
- Using both operands are intergers, the / operator truncates fraction part and returns a integer
- % operator requires integer operands
In C99, result of a division is always truncated toward zero. -9 / 7 = -1, -9 % 7 = -2(파이썬과 다름)
Implementation-Defined Behavior에 의존하는 코드를 가능한 피하는 것이 좋다.
associativity : 여러개의 동등한 우선순위를 가진 operator를 처리하는 순서.
left associative: 왼쪽에서 오른쪽으로 처리함. binary arithmetic operators(*, /, %, +, -)는 모두 left associative.
ex) i - j - k 는 (i - j) - k와 같다
right associative: 오른쪽에서 왼쪽으로 처리함. unary arithmetic oprators(+, -)는 right associative
ex) - + i 는 - (+i)와 같다
12345라는 입력을 5개의 변수에 각각 한 자리 정수로 넣으려면, format string으로 "%1d%1d%1d%1d"를 사용하자.
4. 2 Assignment Operators
simple assignment operator : =
많은 언어에서 assignment는 statement이나, C에서는 operator이다.
다시 말해 = 기호를 사용하는 것은 + 기호를 사용하는 것과 같이 '결과'를 만들어 내는 것.
(v = e: evaulate the expression e and copy its value into v)
i = j = k = 0;의 의미는 i = (j = (k = 0));과 같다. (=> operator is right associative)
lvalue : assignment operator requires an lvalue as its left operand. 지금까지 배운 것에서는 variable만이 lvalue가 될 수 있다.
compound assignment operators : +=
10 compound assignment operators, +=, -+, *=, /=, %=, 등등
v += e가 항상 v = v + e와 동일한 의미를 지니지는 않는다.(side effect)
compound assignment도 = operator와 마찬가지로 right associative.
i += j += k; 는 i += (j += k); 와 동일
4.3 Increment and Decrement Operators
++(increment), --(decrement) operators
prefix(++i, --i), postfix(i++, i--)로 구분된다.
이 연산자는 side effect를 발생시킴(they modify the values of their operands)
prefix는 먼저 값이 변경되고 읽어들인다, postfix는 값을 먼저 읽어들이고 그 다음에 변경된다.
prefix는 먼저 1증가(감소)시키고 읽는다!
postfix는 일단 읽고, 그다음에 1증가(또는 1 감소)
4.4 Expression Evaluation
연산자들을 계산하는 순서
Precedence |
Name |
Symbol(s) |
Associativity |
1 |
increment(postfix) decrement(postfix) |
++ -- |
left |
2 |
increment(prefix) decrement(prefix) unary plus unary minus |
++ -- + - |
right |
3 |
multiplicative |
* / % |
left |
4 |
additive |
+ - |
left |
5 |
assignment |
= *= /= %= += -= |
right |
a = 5;
c = (b = a + 2) - (a = 1);
라는 식이 있을 때, 두 괄호 (subexpression) 중 어떤 것이 먼저 처리되는 것인지는 정의되지 않음. 전자가 먼저 처리되어 c = 6이 될 수도, 후자가 먼저 처리되어 c = 2가 될 수도 있는 것. 위 식은 undefined behavior를 발생시킨다.
그러므로 같은 expression 안에서 한 변수의 값에 접근하기도 하고 변경하기도 하는 것은 피해야 한다.
따라서 이렇게 쓰자
a = 5;
b = a + 2;
a = 1;
c = b - a;
4.5 Expression Statements
C의 어떤 expression이라도 statement가 될 수 있다. expression 뒤에 세미콜론(;)을 붙이면 statement가 된다.
예를 들어, i = 0일 때, i + 1;이라는 라인도 statement이다. 그 statement의 값은 1이 되며, 기껏 덧셈을 수행해 놓고 그 결과가 아무 곳에도 저장되지 않는 것이므로 "do-nothing" expression statement가 된다. 이런 statement가 발생하면 컴파일러에서 헛심을 켜는것에 대해 경고해 준다.