모두의 코드
씹어먹는 C 언어 - <4 - 1. 계산하리>
이번 강의에서는
산술 연산자
대입 연산자
비트 연산자, 쉬프트 연산자
변수에 관한 추가적인 내용
산술 변환, 우선 순위
등을 배우게 됩니다.
안녕하세요 여러분. 지난 강의에서 모두들 변수에 대해 감이 잡혔을 것이라 믿고 강의를 진행하도록 하겠습니다.
최초의 컴퓨터는 무엇을 하기 위해 태어났을까요? 오락용? 영화 시청? (물론 그 때에는 불가능 했을 터이지만). 아닙니다. 최초의 컴퓨터라 일컫어 지는 에니악(ENIAC.. 물론 에니악이 최초의 컴퓨터이냐 아니냐에 관한 논쟁은 길다. 한편에서는 콜로서스라는 주장도 있는데 아무튼) 은 포탄을 어떤 각도로 발사했을 때, 어디에 떨어질 지를 예측하는 기계였습니다.
물론 지금도 컴퓨터의 가장 중요한 역할은 인간이 할 수 없는 복잡한 수식을 계산하는 것입니다. 다시말해, 컴퓨터는 빠른 계산을 위해 태어난 기계인 것입니다.
산술 연산자, 대입 연산자
이번 강좌에서는 C 언어에서 컴퓨터에 어떻게 연산 명령을 내리는지 살펴보도록 하겠습니다.
일단, '계산' 이라 하면 머리속에 가장 먼저 떠오르는 것은 사칙연산, 즉 +, -, ×, ÷ 을 의미합니다. 보통 코딩 시에 × 와 ÷ 기호를 쓰기 힘들기 때문에, 그 대신 *
와 /
를 사용합니다. 즉, 8 × 5 는 8 * 5
로 표현하고, 10 ÷ 7 은 10 / 7
로 표현합니다.
또한, 색다른 연산자로 %
가 있는데 이는 나눈 나머지를 의미합니다. 예를들어 10 % 3
은 1 이 됩니다. 왜냐하면 10 을 3 으로 나눈 나머지가 1 이기 때문이죠. 이러한 +, -, *, /, %
를 산술 연산자(Arithmetic Operator) 라고 합니다.
/* 산술 연산 */ #include <stdio.h> int main() { int a, b; a = 10; b = 3; printf("a + b 는 : %d \n", a + b); printf("a - b 는 : %d \n", a - b); printf("a * b 는 : %d \n", a * b); printf("a / b 는 : %d \n", a / b); printf("a %% b 는 : %d \n", a % b); return 0; }
만약 위 코드를 잘 컴파일 했다면 아래와 같이 나옵니다. (컴파일 하는 방법을 까먹은 사람들은 1강을 참조하세요)
실행 결과
a + b 는 : 13 a - b 는 : 7 a * b 는 : 30 a / b 는 : 3 a % b 는 : 1
그렇다면 코드를 살펴보도록 합시다.
a = 10; b = 3;
지난 강좌를 잘 이해하셧더라면 위 문장이 무슨 역할을 하는지 쉽게 이해하실 수 있을 것입니다. a
라는 변수에 10 을 대입하는 것이고, 두 번째 문장은 b
에 3을 대입하는 것입니다. 그렇다면 아래 문장을 살펴보세요.
10 = a; 3 = b;
언뜻 보기에 맞는 문장인 것 같습니다. 왜냐하면, 실제 수학을 공부한 사람이라면 a = 10
이나 10 = a
나 별반 다를 것이 없기 때문이죠. 하지만, C 언어 컴파일러는 '=' 라는 기호를 뒤에서 부터 해석합니다. 즉, a = 10
은 10 을 a
에 대입하라 라는 문장이 되지만, 10 = a
는' a
의 값을 10 에 대입하라' 라는 이상한 문장이 되서 오류가 발생하게 됩니다.
이렇게 '=' 를 대입 연산자(Assignment Operator) 라고 합니다. 왜냐하면 우측의 값을 좌측에 대입 하는 것이기 때문이죠.
따라서,
a = 5; b = 5; c = 5; d = 5;
라는 문장이나,
a = b = c = d = 5;
라는 문장은 완전히 같은 것이 됩니다. 왜냐하면, 앞에서 말했듯이 =
는 뒤에서 부터 해석한다고 했으므로, 제일 먼저 d = 5
를 해석한 후, 그 다음에 c = d, b = c, a = b
로 차례대로 해석해 나가기 때문에 a = 5; b = 5; c = 5; d = 5;
라는 문장과 같은 것이지요.
printf("a + b 는 : %d \n", a + b); printf("a - b 는 : %d \n", a - b); printf("a * b 는 : %d \n", a* b); printf("a / b 는 : %d \n", a / b); printf("a %% b 는 : %d \n", a % b);
자, 이제 산술 연산자들에 대해 살펴보도록 합시다. 일단, 한 눈에 보게 a + b, a - b, a * b, a / b
는 각각 덧셈, 뺄셈, 곱셈, 나눗셈을 하여서 그 값이 %d
에 들어가 출력된 것 같습니다. 그런데, a + b, a - b, a * b
는 각각 계산 결과가 13, 7, 30
이 나온 사실을 쉽게 받아들일 수 있지만, a / b
가 왜 3 이 나왔는지는 이해하기 힘듭니다. 왜, a / b
가 3 이 되었을까요?
사실, 3 강에서 말했지만 a
와 b
는 모두 int
형으로 선언된 변수 입니다. 즉, a
와 b
는 오직 '정수' 데이터만 담당합니다. 즉, a
와 b
는 모두 정수 데이터만 처리하기 때문에 a
를 b
로 나누면, 즉 10 을 3 으로 나누면 3.3333...
이 되겠지만 정수 부분인 3 만 남기게 되는 것 입니다. 따라서, 값은 3 이 출력됩니다.
마지막으로 생소한 %
라는 연산자에 대해 살펴봅시다. +, -, *, /
연산자는 모두 정수, 실수형 데이터에 대해서 모두 연산이 가능한데, %
는 오직 정수형 데이터에서만 연산이 가능합니다. 왜냐하면 %
는 나눈 나머지를 표시하는 연산자 이기 때문이죠. a % b
는 a
를 b
로 나눈 나머지를 표시합니다. 즉, 10 % 3 = 1
이 됩니다.
이 때,
printf("a %% b 는 : %d \n \n", a % b);
%%
는 %
를 '표시'하기 위한 방법입니다. 왜냐하면 %
하나로는 %d , %f
같이 사용될 수 있기 때문이 표시가 되지 않습니다.
나눗셈 시에 주의할 점
#include <stdio.h> int main() { int a, b; a = 10; b = 3; printf("a / b 는 : %f \n", a / b); // 해서는 안될 짓 return 0; }
컴파일 후 (아마 경고 메세지가 뜰 것입니다), 실행한다면 아래와 같이 이상한 결과가 나옵니다.
실행 결과
a / b 는 : 0.000000
3 강 에서 우리는 %f
가 오직 실수형 데이터 만을 출력하기 위해 있는 것이라 하였습니다. 그런데, a / b
가 10 나누기 3 이므로 3.3333... 이 되서 해서 실수형 데이터가 되는 것이 아닙니다.
(정수형 변수) (연산) (정수형 변수)
는 언제나 (정수)
으로 유지됩니다. 따라서, 실수형 데이터를 출력하는 %f
를 정수형 값 출력에 사용하면 위와 같이 이상한 결과가 나오게 됩니다.
그렇다면 아래의 경우 어떻까요?
/* 산술 변환 */ #include <stdio.h> int main() { int a; double b; a = 10; b = 3; printf("a / b 는 : %f \n", a / b); printf("b / a 는 : %f \n", b / a); return 0; }
만약 제대로 컴파일 했다면 아래와 같이 나오게 됩니다.
실행 결과
a / b 는 : 3.333333 b / a 는 : 0.300000
a
는 정수형 변수, b
는 실수형 변수 입니다. 그런데, 이들에 대해 연산을 한 후에 결과를 실수형으로 출력하였는데 정상적으로 나왔습니다. 그 것은 왜 일까요? 이는 컴파일러가 산술 변환 이라는 과정을 거치기 때문입니다. 즉, 어떠한 자료형이 다른 두 변수를 연산 할 때, 숫자의 범위가 큰 자료형으로 자료형들이 바뀝니다.
즉, 위 그림에서도 보듯이 a
가 int
형 변수이고 b
가 double
형 변수인데, double
이 int
에 비해 포함하는 숫자가 더 크므로 큰 쪽으로 산술 변환됩니다.
일단, 정수형 변수와 실수형 변수가 만나면 무조건 실수형 변수쪽으로 상승되는데, 이는 실수형 변수의 수 범위가 int
보다 훨씬 넓기 때문입니다. 위와 같은 산술 변환을 통해 애러가 없이 무사히 실행 될 수 있었습니다. 또한 double
형태로 산술 변환 되므로 결과도 double
형태로 나오기 때문에
printf(" a / b 는 : %d \n", a / b);
와 같이 하면 오류가 생기게 됩니다. 왜냐하면 %d
는 정수형 값을 출력하는 방식이기 때문이죠.
대입 연산자
/* 대입 연산자 */ #include <stdio.h> int main() { int a = 3; a = a + 3; printf("a 의 값은 : %d \n", a); return 0; }
위 결과를 컴파일 하면 아래와 같이 나옵니다.
실행 결과
a 의 값은 : 6
일단, 변수 선언 부분 부터 살펴 봅시다.
int a = 3;
위 문장을 아마 무슨 뜻일지 감이 바로 오실 것입니다. "음... a
라는 변수를 선언하고 a
변수에 3 의 값을 집어 넣는구나". 맞습니다. 사실 위 문장이나 아래 문장이나 다를 바가 없습니다.
int a; a = 3;
그냥, 타이핑 하기 귀찮아서 짧게 써 놓은 것 뿐입니다.
a = a + 3;
그 다음 부분은 대입 연산자와 산술 연산자가 함께 나와 있습니다. 만일, 우리가 방정식에 대해서 공부해 본 사람이라면 다음과 같이 이의를 제기할 수 도 있습니다.
a = a + 3 따라서 양변에서 a 를 빼면 0 = 3 ???
물론, 위는 수학적으로 맞지만 C 언어 에서 의미하는 바는 다릅니다. 위에서 말했듯이, =
는 등호가 아닙니다. '대입' 연산자 입니다. 무엇을 대입하냐구요? 오른쪽의 값을 왼쪽으로 대입합니다. 즉, a + 3
의 값(6) 을 a
에 대입합니다. 따라서, a = 6
이 되는 것이지요.
이 때, 이와 같이 계산 될 수 있는 이유는 +
를 =
보다 먼저 연산하기 때문입니다. 즉, a + 3
을 먼저 한 후(+), 그 값을 대입(=) 하는 순서를 거치기 때문에 a
에 6 이라는 값이 들어갈 수 있게 됩니다. 이러한 것을 연산자 우선순위 라고 하는데, 밑에서 조금 있다가 다루어 보도록 하겠습니다.
/* 더하기 1 을 하는 방법 */ #include <stdio.h> int main() { int a = 1, b = 1, c = 1, d = 1; a = a + 1; printf("a : %d \n", a); b += 1; printf("b : %d \n", b); ++c; printf("c : %d \n", c); d++; printf("d : %d \n", d); return 0; }
위 코드를 컴파일 하면 아래와 같이 나옵니다.
실행 결과
a : 2 b : 2 c : 2 d : 2
음, 모두 2 가 되었군요. 사실 위에 나온 4 개의 코드는 더하기 1 을 한다는 점에서 모두 같습니다. 일단, 하나하나 차례대로 살펴봅시다.
a = a + 1;
가장, 기초적으로 1 을 더하는 방법입니다. 위 문장은 "a
에 a
에 1 을 더한 값을 대입한다." 라는 뜻을 가지고 있죠?
b += 1;
이게 뭔가요! 처음 본 연산인 +=
입니다. 이러한 연산을 복합 대입연산 이라 하며, b = b + 1
과 같습니다. 이렇게 쓰는 이유는 단지, b = b + 1
을 쓰기 귀찮아서 간략하게 쓰는 것입니다. 물론, b = b + 1
과 b += 1
은 엄밀히 말하자면 같은 것은 아니지만 이에 대해서는 나중에 다루어 보도록 하겠습니다(우선 순위에서 약간 차이가 있습니다). 복합 대입 연산은 아래와 같이 여러 가지 형태로 이용될 수 있습니다.
b += x; // b = b + x; 와 같다 b -= x; // b = b - x;와 같다 b *= x; // b = b * x;와 같다 b /= x; // b = b / x;와 같다
마지막으로, 비슷하게 생긴 두 부분을 함께 살펴 보도록 하겠습니다.
++c; d++;
위와 같은 연산자(++
)를 증감 연산자라고 합니다. 둘 다, c
와 d
를 1 씩 증가시켜 줍니다. 그런데, ++
의 위치가 다릅니다. 전자의 경우 ++
이 피연산자(c
) 앞에 있지만 후자의 경우 ++
이 피연산자(d
) 뒤에 있습니다.
++
이 앞에 있는 것을 전위형(prefix), ++
이 뒤에 있는 것을 후위형(postfix) 라 하는데 이 둘은 똑같이 1 을 더해주만 살짝 다릅니다. 전위형의 경우, 먼저 1 을 더해준 후 결과를 돌려주는데 반해, 후위형의 경우 결과를 돌려준 이후 1 을 더해줍니다. 이 말만 가지고는 이해가 잘 안될테니 아래를 보세요.
/* prefix, postfix */ #include <stdio.h> int main() { int a = 1; printf("++a : %d \n", ++a); a = 1; printf("a++ : %d \n", a++); printf("a : %d \n", a); return 0; }
위 소스를 성공적으로 컴파일 했다면 아래와 같이 결과가 나온다.
실행 결과
++a : 2 a++ : 1 a : 2
분명히, 위에서 ++c
나 d++
이나 결과를 출력했을 때 에는 결과가 1 이 잘 더해져서 2 가 나왔는데 여기서는 왜 다르게 나올까요? 앞서 말했듯이 ++ a
는 먼저 1 을 더한 후 결과를 반환한다고 했고 a++
은 먼저 결과를 반환 한 후, 그 후에 1 을 더한 다고 했습니다.
printf("++a : %d \n", ++a);
즉, 위의 경우 a
에 먼저 1 을 더한 값인 2 를 printf 함수에 반환하여 %d
에 2 가 들어가게 됩니다. 그런데,
printf("a++ : %d \n", a++);
이 경우, 먼저 a
의 값을 printf 에 반환하며 %d
에 1 이란 값이 '먼저' 들어 간 뒤, 1 이 출력된 이후 a
에 1 이 더해집니다. 따라서, 다시 printf 문으로 a
의 값을 출력하였을 때 에는 2 라는 값이 나오게 되는 것입니다. 참고로, 위 4 개의 연산 중에서 가장 빨리 연산되는 것은 a++
과 같은 증감 연산입니다 하지만, 요즘의 컴파일러는 최적화가 잘 되어 있어, a = a + 1
같은 것은 a++
로 바꾸어 컴파일 해버립니다.
비트 연산자
마지막으로 비트 연산자라고 불리는 생소한 연산자들에 대해 이야기 해보겠습니다. 이 연산자들은 정말 비트(bit) 하나 하나에 대해 연산을 합니다. 비트는 컴퓨터에서 숫자의 최소 단위로 1 비트는 0 혹은 1 을 나타내죠. 쉽게 말해 이진법의 한 자리라 볼 수 있습니다.
보통, 8개의 비트(8 bit) 를 묶어서 1 바이트(byte) 라고 하고, 이진법으로 8 자리 수라 볼 수 있습니다. 따라서, 1 바이트로 나타낼 수 있는 수의 범위가 0 부터 11111111 로 십진수로 바꾸면 0 부터 255 까지 나타낼 수 있습니다.
비트 연산자에는 &
(And 연산), |
(\ 위에 있는 것. 영문자 i
의 대문자가 아닙니다. Or 연산), ^
(XOR 연산), <<, >>
(쉬프트 연산) , ~
(반전) 등이 있습니다. 일단, 각 연산자가 어떠한 역할을 하는지 살펴보도록 합시다.
AND 연산 (&)
AND 연산은 아래와 같은 규칙으로 연산됩니다.
|
| 결과 |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
비트 연산은 각 자리를 연산하는데, 예를들어, 1010 & 0011
의 경우
위와 같이 한자리 한자리 각각 AND 연산하여, 위에 써 놓은 규칙대로 연산이 됩니다. 만약 두 숫자의 자리수가 맞지 않을 경우, 예를들어 1111100 과 11 을 AND 연산 할 때 에는 11 앞에 0 을 추가하여 자리수를 맞추어 줍니다. 즉, 1111100 과 0000011 의 연산과 같습니다.
OR 연산 (|)
|
| 결과 |
---|---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
OR 연산은 AND 연산과 대조적입니다. 어느 하나만 1 이여도 모두 1 이 되는데, 예를들어 1101 | 1000
은 결과가 1101 이 됩니다.
XOR 연산 (^)
|
| 결과 |
---|---|---|
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
XOR 연산은 특이하게도 두 수가 달라야지만 1 이 됩니다. 예를들어, 1100 ^ 1010
의 경우 결과가 0110 이 됩니다. 마치 두 비트를 더한 다는 식으로 생각하시면 됩니다.
반전 연산(~)
반전연산은 간단히 말에 0 을 1 로 1 을 0 으로 바꿔주는 것입니다. 예를들어서 ~1100
을 하면 그 결과는 0011 이 됩니다.
<< 연산 (쉬프트 연산)
위 연산 기호에서 느껴지듯이 비트를 왼쪽으로 쉬프트(Shift) 시킵니다. 예를 들어, 101011 를 1 만큼 쉬프트 시키면 ( 이를 a << 1
이라 나타냅니다)
위 처럼 결과가 010110 이 됩니다. 이 때, <<
쉬프트 시, 만일 앞에 쉬프트된 숫자가 갈 자리가 없다면, 그 부분은 버려집니다. 또한 뒤에서 새로 채워지는 부분은 앞에서 버려진 숫자가 가는 것이 아니라 무조건 0 으로 채워집니다.
>> 연산
이는 위와 같은 종류로 이는 <<
와 달리 오른쪽으로 쉬프트 해줍니다. 이 때, 오른쪽으로 쉬프트 하되, 그 숫자가 갈 자리가 없다면 그 숫자는 버려집니다. 이 때, 무조건 0 이 채워지는 <<
연산과는 달리 앞부분에 맨 왼쪽에 있었던 수가 채워지게 되죠. 예를들어서 11100010 >> 3 = 11111100
이 되고, 00011001 >> 3 = 00000011
이 됩니다.
비트 연산자를 자세히 다룬 이유는 이 연산자가 여러분들이 아마 여태까지 살면서 다루어왔던 연산자들 (덧셈, 뺄셈 같은 애들) 과는 조금 다르기 때문입니다. 또한, 처음에 비트 연산자를 접할 때, 저런거 뭐에다 쓰지? 라는 생각이 들기도 합니다. 아직은 그 쓰임새를 짚고 넘어가기 어렵지만 나중에 종종 등장할 때가 있을 테니, 잘 기억해놓으시기 바랍니다.
/* 비트 연산 */ #include <stdio.h> int main() { int a = 0xAF; // 10101111 int b = 0xB5; // 10110101 printf("%x \n", a & b); // a & b = 10100101 printf("%x \n", a | b); // a | b =10111111 printf("%x \n", a ^ b); // a ^ b = 00011010 printf("%x \n", ~a); // ~a = 1....1 01010000 printf("%x \n", a << 2); // a << 2 = 1010111100 printf("%x \n", b >> 3); // b >> 3 = 00010110 return 0; }
위를 성공적으로 컴파일 했다면
실행 결과
a5 bf 1a ffffff50 2bc 16
위와 같이 나오게 됩니다. 일단, 첫 세줄은 그럭 저럭 이해가 잘 갑니다. 그런데, 네 번째 줄인 ~a
연산에 대해 의문을 품는 사람들이 많습니다.
printf("%x \n", ~a); // ~a = 1....1 01010000
우리의 기억을 되돌려 3 강으로 가 봅시다. 강의 중간쯤에 보면 여러가지 자료형 들에 대한 설명과 함께 작은 표가 있을 텐데 말이죠. 이를 다시 아래에 불러와 봅시다.
int
형 변수에 대한 설명을 보니 옆에 Size 이라 표시된 것이 있습니다. 이는 int
형 변수의 크기를 나타내는데 4 바이트라고 되어 있군요. 맞습니다. int
형 변수는 하나의 데이터를 저장하기 위하여 메모리 상의 4 바이트 - 즉 32 비트를 사용합니다. (1 byte = 8 bits) 아까, 하나의 비트가 0 과 1 을 나타낸다고 했으므로 (즉 1 개의 비트가 2 진수의 한 자리를 나타내게 되죠), 하나의 int
형 변수는 32 자리의 이진수라고 볼 수 있습니다. 예를들어 우리가 a = 1
이라 한 것은 실제로 컴퓨터에는 a = 00000000 00000000 00000000 00000001
이라 저장되는 것과 같게 되는 거죠.
즉, 우리가 int a = 0xAF;
라고 한 것은 a = 10101111;
이 맞지만 사실 컴퓨터 메모리 상에서는 a
가 int
형이기 때문에 a = 00000000 00000000 00000000 10101111
(10101111
앞에 0 이 24 개 있다) 이라 기억하는 것이 됩니다. 따라서, 이 숫자를 반전 시키게 되면
a = 11111111 11111111 11111111 01010000
, 즉 0xFFFFFF50
이 되는 것이지요. 마찬가지로 생각해 보면,
printf("%x \n", a << 2); // a << 2 = 1010111100 printf("%x \n", b >> 3); // b >> 3 = 00010110
이 두 문장도 사실은 각각 00000000 00000000 00000000 10101111
과 00000000 00000000 00000000 10110101
을 쉬프트 연산한 것과 같습니다.
따라서 a
의 경우 00000000 00000000 00000000 10101111
을 왼쪽으로 2 칸 쉬프트 하면 00000000 00000000 00000010 10111100
이 되어 0x2BC
가 됩니다
b
의 경우 마치 앞에 1 이 있는 것 같지만 실제로는 int
형 데이터에 저장되어 있으므로 4 바이트로, 00000000 00000000 00000000 10110101
이므로 맨 왼쪽의 비트는 0 입니다. 따라서 쉬프트를 하게 되면 왼쪽에 0 이 채워지면서 00000000 00000000 00000000 00010110
이 되어 0x16
이 됩니다.
복잡한 연산
마지막으로 여러 연산이 중첩된 혼합 연산에 대해 살펴 보도록 합시다. 우리가 연산을 하는데 에도 순서가 있듯이 컴퓨터에도 연산을 하는데 무엇을 먼저 연산을 할 지 우선 순위가 정해져 있을 뿐더러 연산 방향 까지도 정해져 있습니다. 이를 간단히 살펴 보자면 아래와 같습니다.
이와 같이 순위가 매겨져 있습니다. 이 때, 눈여겨 보아야 할 점은 괄호들이 제 1 우선 순위에 위치하였다는 점 입니다. 따라서, 어떠한 연산이라도 괄호로 감싸 주게 되면 먼저 실행 됩니다.
마지막으로, 결합 순위에 대해 잠시 다루어 보도록 하겠습니다. 표의 오른쪽을 보면 결합 순위가 나와 있는데, 대부분이 '왼쪽 우선' 이지만 몇 개는 '오른쪽 우선' 입니다. 이 말이 뜻하는 바가 무엇이냐면, 아래와 같은 문장을 수행할 때 계산하는 순위를 이야기 합니다.
a = b + c + d + e;
위 표에서 보듯이, 덧셈의 결합 순서가 왼쪽 우선이므로 위 계산과정은 아래의 순서대로 진행됩니다.
b + c
를 계산하고 그 결과를 반환( 그 결과를C
라 하면)C + d
를 계산하고 그 결과를 반환( 그 결과를D
라 하면)D + e
를 계산하고 그 결과를 반환(그 결과를E
라 하면)
따라서, 위 식은
a = E
가 되죠. 따라서, a
에 E
의 값, 즉 b + c + d + e
의 값이 들어가게 됩니다.
또한, 위 표에서 몇 안되는 '오른쪽이 우선' 인 대입 연산자(=) 를 살펴봅시다. 만약 대입 연산자가 왼쪽 우선이였다면 아래의 식이 어떻게 계산될 지 생각해 봅시다.
a = b = c = d = 3;
만약 왼쪽 우선이였다면 a = b; b = c; c = d; d = 3
의 형식으로 계산되어 a, b, c
에는 알 수 없는 값이 들어가겠죠. 하지만 오른쪽이 우선이므로 위 식은 d = 3, c = d, b = c, a = b
의 형식으로 계산되어 a,b,c,d
의 값이 모두 3 이 될 수 있었습니다.
자, 이제 연산자에 대한 강의가 끝났습니다. 연산자는 C 언어에서 가장 기초적인 부분이라 할 수 있습니다. 마치 수학에서 덧셈, 뺄셈을 가장 처음에 배우는 것 처럼 말이죠.
이번 강좌에서는 특별히 예제를 많이 만들어 보지는 않았지만 여러분 께서 C 언어를 통해 복잡한 수식의 계산을 하거나, 복잡한 수식을 보고 이러한 연산은 이 순서로 연산될 것이다 라고 예측해 보는 것도 우선순위를 이해하는데 도움이 될 것입니다. 보통, 우선순위를 잘못 고려하여 나는 오류들은 찾기가 매우 힘들기 때문에 애초에 헷갈릴 만한 부분은 괄호를 통해 확실하게 하는 것이 좋습니다.
뭘 배웠지?
+, -, /, *, =, %
가 무슨 역할을 하는 연산자 인지 배웠습니다.
&, |, <<, >>
가 무슨 역할을 하는 연산자 인지 배웠습니다.
연산자 우선 순위에 대해 다루었습니다.
우선 순위가 헷갈리거나, 복잡한 수식이면 괄호를 적극 활용합니다.
댓글을 불러오는 중입니다..