Expressions adopted from KNK C Programming : A Modern Approach
Operators 연산자 C 는표현식을많이사용함 표현식은변수와상수와연산자로구성됨 C 에는연산자의종류가다양함 1. arithmetic operators ( 수식연산자 ) 2. relational operators ( 관계연산자 ) 3. logical operators ( 논리연산자 ) 4. assignment operators ( 할당연산자 ) 5. increment and decrement operators ( 증감연산자 ) 그외에도더있음 2
Arithmetic Operators 수식연산자 C 이항수식연산자 arithmetic operators: + addition - subtraction An operator is binary if it has two operands. * multiplication / division Ex: A*B, A+B % remainder 단항수식연산자 : + unary plus - unary minus i = +1; j = -i; 음수양수구분용 3
Binary Arithmetic Operators i % j 의값은 i 를 j 로나눈나머지. 10 % 3 의값은 1, 12 % 4 는 0. 이항수식연산자는 % 를제외하면정수와실수피연산자를혼용해서쓸수있음 int 와 float 형피연산자가혼용되면결과는 float. 9 + 2.5f 의결과는 11.5, 6.7f / 2 는 3.35. 4
/ 와 % 연산자 / 와 % 는주의를요하는연산자 : 두피연산자가정수면, / 소수점이하는버림. 1 / 2 의결과는 0 이다. 0.5 가아님. % 연산자는정수만피연산자로받음 ; 어느하나라도정수가아니면컴파일이안됨 우측피연산자로 0 을쓸경우 / 또는 % 는정의되지않은동작을함 v/ 과 % 에음수피연산자가사용될경우 C89 의경우 implementationdefined( 구현에따라다름 ). v C99 에서는, 나눗셈의결과는항상 0 방향으로내림, 그리고 i % j 의결과는 i 의부호와같음. 5
Operator Precedence ( 연산자우선순위 ) i + j * k 의의미가 i 와 j 를더하고, 그결과를 k 로곱하라 일까 j 와 k 를곱하고, i 를더하라 일까? 명확히하는방법은 (i + j) * k 또는 i + (j * k) 처럼괄호로묶는것. 괄호가없으면, C 는연산자우선순위 operator precedence 규칙에따라처리함 우선순위를모를때는괄호를써서먼저계산한것을표시! 6
Operator Precedence 수식연산자의우선순위는간략하게다음과같음 : Highest: + - (unary) * / % Lowest: + - (binary) Examples: i + j * k 와 i + (j * k) 는동치 -i * -j 와 (-i) * (-j) 는동치 +i + j / k 와 (+i) + (j / k) 는동치 7
Operator Associativity ( 연산자결합 ) Associativity 결합은동일한우선순위의연산자들이포함된수식에서적용됨 연산자들의결합방향이왼쪽에서오른쪽으로진행된다면 left associative 왼쪽결합 이항수식연산자 (*, /, %, +, -) 는 left associative i - j k 와 (i - j) - k 는동치 i * j / k 와 (i * j) / k 는동치 연산의결합방향이오른쪽에서왼쪽이면 right associative 오른쪽결합. 단항수식연산자 (+, -) 는 right associative - + i 와 -(+i) 는동치 8
Assignment Operators 할당연산자 1. Simple assignment 단순할당 : 변수에값저장에사용 2. Compound assignment 합성할당 : 변수에저장된값을갱신할때사용 9
Simple Assignment 단순할당 v = e 은 e 의표현식의값을 v 로복사하라는말과같음 e 상수일수도또는복잡합표현식일수있음 : i = 5; /* i is now 5 */ j = i; /* j is now 5 */ k = 10 * i + j; /* k is now 55 */ 만약 v 와 e 가같은형이아니면 e 의형은 v 의형으로변환됨 int i; float f; i = 72.99f; /* i is now 72 */ f = 136; /* f is now 136.0 */ 10
Side Effects 피연산자의값을변형시키는연산자를 side effect 가있다고함 단순할당연산자는 side effect 가있음 : 좌변의변수를변경함 i = 0 를분석해보면우변의결과는 0 이됨. 그리고 side effect 로인해 i 에 0 을저장함. 할당은연산자이기때문에여러할당연산이한줄에사용될수있음 : i = j = k = 0; = 는오른쪽결합이기때문에아래와동치임 i = (j = (k = 0)); 11
Side Effects 그러나한줄에할당을여러번할경우값이변환되는경우를주의해야함 : int i; float f; f = i = 33.3f; i 는 33 를저장, f 는 33.0 (not 33.3) 을저장. 12
Side Effects v = e 형태의할당은 v 의타입이허용되는모든경우에대해사용할수있음 : i = 1; k = 1 + (j = i); // 수식내에할당을포함할경우 // 읽기어렵고, 버그의온상임 printf("%d %d %d\n", i, j, k); /* prints "1 1 2" */ 13
Lvalues 할당연산자는왼쪽피연산자로 lvalue 를필요로함. lvalue 는컴퓨터메모리에저장된객체로서상수도계산결과도아님. 변수가 lvalues 임 ; 10 또는 2 * i 는아님. 12 = i; /*** WRONG ***/ i + j = 0; /*** WRONG ***/ -i = j; /*** WRONG ***/ 컴파일러는이런경우 invalid lvalue in assignment. 라는오류메시지를출력함 14
Compound Assignment 합성할당 변수의과거의값을사용하여새로운값을다시원래의변수에저장하는경우는매우흔함 Example: i = i + 2; += 합성할당연산자로간단하게표현할수있음 : i += 2; /* same as i = i + 2; */ 15
Compound Assignment 합성할당연산자는소개한것외에도 9개가더있음. 그중일부는 : -= *= /= %= 모든합성할당연산자는동일한방식으로동작 : v += e : v 를 e 에더하고, v 에결과저장 v -= e : v 를 e 에서빼고, v 에결과저장 v *= e : v 를 e 와곱하고, v 에결과저장 v /= e : v 를 e 로나누고, v 에결과저장 v %= e : v 를 e 로나눈나머지를, v 에저장 v += e 가 v = v + e 언제나동치는아님. 연산자우선수위가있기때문에 i *= j + k 는 i = i * j + k 와동치가아님 16
Increment and Decrement Operators 증감, 가감연산자 변수에가장자주사용되는연산은 증가 ( 더하기 1) 그리고 가감 ( 빼기 1): C 는이를위해 ++ ( 증가 ) 그리고 -- ( 감소 ) 연산자제공. ++ 연산자는피연산자에 1 을더하고, -- 연산자는 1 을뺌. prefix 연산자 (++i, -i) 또는 postfix 연산자 (i++, i--). i = i + 1; j = j - 1; i += 1; j -= 1; i++; ++i; j--; --i; 합성할당연산자 증가감소연산자 17
Increment and Decrement Operators ++i ( 먼저더함 ) 는 i + 1 를뜻하고 side effect 로 i 는증가됨 i = 1; printf("i is %d\n", ++i); /* prints "i is 2" */ printf("i is %d\n", i); /* prints "i is 2" */ i++ ( 후에더함 ) 의결과는 i 이고, 그다음 i 의값이증가됨 i = 1; printf("i is %d\n", i++); /* prints "i is 1" */ printf("i is %d\n", i); /* prints "i is 2" */ ü++i 는 i 를즉시증가 를뜻함 üi++ 는 현재의 i 값을쓰고, 그후에 i 를증가 를뜻함 18
Increment and Decrement Operators -- 연산자도똑같은성질을갖음 : i = 1; printf("i is %d\n", --i); /* prints "i is 0" */ printf("i is %d\n", i); /* prints "i is 0" */ i = 1; printf("i is %d\n", i--); /* prints "i is 1" */ printf("i is %d\n", i); /* prints "i is 0" */ 19
Increment and Decrement Operators ++ 또는 가한표현식에서여러차례사용된다면그결과를판단하기어려워짐 Example: i = 1; j = 2; k = ++i + j++; 마지막문장은다음과같음 i = i + 1; k = i + j; j = j + 1; 최종결과로 i, j, k 는 2, 3, 4 가됨 20
Increment and Decrement Operators 다음의문장을실행시키면 i = 1; j = 2; k = i++ + j++; i, j, k 는 2, 3, 3 이됨. 21
표현식평가 지금까지다룬연산자 : 우선순위 이름 기호 결합방향 1 increment (postfix) ++ left decrement (postfix) -- 2 increment (prefix) ++ right decrement (prefix) -- unary plus + unary minus - 3 multiplicative * / % left 4 additive + - left 5 assignment = *= /= %= += -= right 22
표현식평가 괄호를써서표현식을묶는방식으로평가할수있음 가장높은우선순위의연산자를중심으로연산자와피연산자를괄호로묶음 Example: a = b += c++ - d + --e / -f Precedence level a = b += (c++) - d + --e / -f 1 a = b += (c++) - d + (--e) / (-f) 2 a = b += (c++) - d + ((--e) / (-f)) 3 a = b += (((c++) - d) + ((--e) / (-f))) 4 (a = (b += (((c++) - d) + ((--e) / (-f))))) 5 23
하위표현식의평가순서 Example: i = 2; j = i * i++; j 의값이 4 라고생각하기쉬움. 하지만 j 는 6 일수도있음 : 1. 두번째피연산자가 (i 의원래값 ) 사용되고, i 가증가됨 2. 첫번째피연산자가 (i 의새로운값 ) 사용됨 3. i 의원래값과새로운값이곱해져 6 이됨. 24
Expression Statements C 에선모든표현식이문장이될수있음. Example: ++i; i 가먼저증가되고, 그새로운값을읽었지만어디에쓰이진않음 side effect 가있는경우만표현식이문장으로서가치가있음 : i = 1; /* useful */ i--; /* useful */ i * j - 1; /* not useful */ 25