연산자는 인간이 원초적으로 계산을 하기 위해 고안한 기호표시 시스템입니다. 구글 검색을 하면 교과서적으로 내용이 잘 나와있어서 그 뜻을 의미하는 것은 어렵지 않을겁니다.
컴퓨터 코딩에서의 연산자는 아래 포스팅이 잘 정리를 해뒀더군요. 원래 다른 티스토리 블로거들 링크는 잘 안다는데 워낙 내용이 좋아서 링크를 달아봅니다.
교과서는 교과서이고 연산자에 대한 내용을 가능한 창의적으로 포스팅하려고 합니다. 교과서적인 부분은 그간 C++ 포스팅 등을 통해 많이 다루기도 했구요.
잘 보면 다트의 연산자나 다른 언어의 연산자나 큰 차이가 없습니다. 우리가 사용하는 문법은 거의 비슷해서 한 두개의 언어를 배우면 나머지 수십개의 비슷한 연산자를 사용하는 언어를 배우고 적응하는데 그리 오래 걸리지 않습니다.
그것은 연산이 컴퓨터 공학의 핵심이기 때문입니다. compute, operate 계산하기 위해서 작업(operation)을 하는 건데 연산하는 그 자체가 컴퓨터라고 할 수 있습니다. 컴퓨터는 계속 연산의 결과를 반환하고 다시 그 사이클을 무한 반복하는 기계입니다.
연산자의 특징을 살펴보면 1. 피연산자가 있다. 2. 결과를 반환한다 - 입니다. 이게 함수와 헷갈릴 때가 있는데 함수도 매개변수를 피연산자로 return 값을 결과로 사용하는 구조입니다. 단 함수는 단순 연산자 보다 더 복잡한 구조(분기, 루프 등)를 만들 수 있지요.
연산자를 조합한 명령어(instruction)를 모아서 함수를 만들 수 있습니다. 함수에는 매개변수가 필요할 수도 없을수도 또 반환값(return value)이 필요할 수도 없을 수도 있지만 함수가 만들어지기 위해서 연산자가 필요하다는 사실은 분명합니다.
함수가 더 큰 개념이면 연산자보다 작은 것은 CPU의 명령어(instruction)입니다. CPU 명령어를 사용하는 방법은 원초적으로 논리회로가 필요하지만 프로그래머는 어셈블리어로 명령어 세트(instruction set)를 사용할 수 있습니다. 물론 이 경우도 OS(운영체제)의 system call을 사용해서 가능하지요. system call은 명령어 세트와 가장 밀접하게 연결되어 있기 때문에 사실상 하드웨어를 직접 조종하는 것과 같은 효과를 갖습니다. 연산자는 직접 CPU의 레지스터를 사용하진 않지만 결국은 어셈블리어로 변환되고 그것이 기계어에 1대1 대응되기 때문에 가장 낮은 단계, 즉 저수준 프로그래밍의 분야라 할 수 있습니다.
연산자의 어려운 점은... 나중에 연산자 오버로딩 혹은 오버라이딩을 하게 될 때 구체적으로 재정의해서 사용하는데 재정의하면 의미가 달라져서 각각 의미를 새로 배워야 하는 부분이 어렵지요.
*다트도 가장 표준적인 C스타일의 연산자를 사용하기 때문에 오늘은 너무 겁먹을 필요가 없습니다. 쉽게쉽게 접근하는게 중요합니다.
void main() {
/*
+ 덧셈 ''
- 뺄셈 ''
* 곱셈 ''
/ 나눗셈 ''
= 할당 연산자
*/
print("덧셈 : 4 + 3 = ${4 + 3}");
print("뺄셈 : 4 - 3 = ${4 - 3}");
print("곱셈 : 4 * 3 = ${4 * 3}");
print("나눗셈 : 4 / 3 = ${4 / 3}");
int a;
print("할당: a = 5를 할당. (${a = 5}) 반환값");
a = 10;
print("증가연산자(후위 postfix): a++ => ${a++}");
print("-> 결과: a = ${a}");
print("증가연산자(선위 prefix): ++a => ${++a}");
print("-> 결과: a = ${a}");
print("a += 3 -> ${a += 3} 자기 자신에 더함");
print("a -= 2 -> ${a -= 2} 자기 자신에 뺌");
}
출력은 다음과 같습니다. $ { } 안에서 표현식으로 사용하는 겁니다. (String Interpolation)
셈 : 4 + 3 = 7
뺄셈 : 4 - 3 = 1
곱셈 : 4 * 3 = 12
나눗셈 : 4 / 3 = 1.3333333333333333
할당: a = 5를 할당. (5) 반환값
증가연산자(후위 postfix): a++ => 10
-> 결과: a = 11
증가연산자(선위 prefix): ++a => 12
-> 결과: a = 12
a += 3 -> 15 자기 자신에 더함
a -= 2 -> 13 자기 자신에 뺌
이 정도면 C의 연산자 문법과 거의 똑같은 거 아닌가... 언어간 공통점이 있는 부분은 잘 숙지하고 조금씩 다른 부분은 좀 들여다 보고 기억할 필요가 있습니다.
문자열 연산자를 숫자 연산자와 비교해보면 연산자가 무엇인지 좀 더 인사이트를 얻을 수 있습니다. 연산의 규칙이 있고 이를 적용할 피연산자가 있고 그 규칙에 따라서 나오는 결과물이 있습니다. 입력이 있고 출력이 있는 논리게이트와 비슷하지요. 개념은 어렵지 않습니다. 두 문자열을 더할려면? + 로 더하면 된다. 반복하려면 * 로 곱하면 된다 - 이런 식입니다. 파이썬 같은 경우 ** 를 사용하고 C언어에는 문자열 *는 없으니까 언어마다 문자열 연산자에 미묘한 차이가 있습니다.
void main() {
// 문자열 연산자
String concat1 = "우주는" + " 광대하다!";
print(concat1);
String concat2 = "하이!" * 3;
print("하이!x3=" + concat2);
String compare = "Hello";
print("Hello == Hello -> " + ("Hello" == compare).toString());
String myIndex = "President";
print("President의 3번째 글자는? " + myIndex[2]);
}
출력은 다음과 같습니다.
우주는 광대하다!
하이!x3=하이!하이!하이!
Hello == Hello -> true
President의 3번째 글자는? e
어떤 언어라도 연산자 형식만 알면 그 다음 부터 좀 더 학습이 수월합니다. 왜냐하면 이 연산자들이 여러개 합쳐져서 함수를 만들고 전체 프로그램을 구성하기 때문입니다. 밑바닥을 다진다고 할까요. 연산자 부분이 매우 지루하긴 하지만 나중에 보상이 썩 나쁘지는 않을 겁니다.