SturdyCobble's Study Note

[프로그래밍] 4.1 연산자(1) - 산술,대입,증감 연산자 본문

휴지통/['19.06-'20.07]프로그래밍101

[프로그래밍] 4.1 연산자(1) - 산술,대입,증감 연산자

StudyingCobble 2019. 8. 12. 16:01

NOTICE : 독학인 만큼, 잘못된 내용이 있을 수 있습니다. 내용 지적은 언제나 환영합니다.

더 이상 이 블로그에는 글을 올리지는 않을 예정입니다. 그렇지만 댓글을 달아주시면 최대한 답변드리고자 노력하겠습니다.


 

※이 글은 프로그래밍 언어에 대한 기초적인 이해를 가정하고 있습니다. 최소 프로그래밍 언어 하나 정도를 약간이라도 접해보시는 것을 추천합니다. 또한, 이 글은 심화 내용은 되도록 피하여 서술했습니다.

프로그래밍 언어에는 다양한 종류의 연산자(Operator)가 존재합니다. 이번 글과 이어진 몇 개의 글에서는 기본적인 연산자들에 대해서 알아봅니다. 그 외의 다양한 연산자는 관련된 글에서 소개하겠습니다.

 

 이러한 연산자를 요구되는 항의 수에 따라, 단항, 이항, 삼항 연산자 등으로 나눌 수도 있지만, 여기서는 일반적으로 프로그래밍 입문 서적들이 그러하듯 용도가 비슷하거나 형태가 비슷한 형태끼리 묶어서 소개하겠습니다.

 

 이번 글에서는 산술(Arithmetic), 대입(Assignment), 증감(Increment and decrement) 연산자 대해서 소개합니다. (이 용어는 언어마다 약간씩 다를 수 있습니다.)

 

다음 표는 이 글에서 언급될 연산자들입니다.

 

C C++ Java Python

+ - * / %

O
** //       O
+= -= *= /= %= O
**= //=       O
++ -- O O O  

 

먼저 산술 연산자입니다. 다음 연산자들은 우리가 사용하는 형태와 거의 유사하며, 사용법도 유사합니다. 우선순위도 우리가 아는 곱셈, 나눗셈 먼저, 왼쪽부터입니다.

 

C

C++ / Java

(*Java는 자동 형변환이 거의 없음.)

Python

(*숫자에 복소수 포함.)

 +

덧셈

덧셈, 결합(문자열 사이)

덧셈,
결합(str,list,tuple)
(같은 자료형 사이에서 결합)

-

뺄셈

*

곱셈

곱셈,
반복
(문자열/리스트/튜플과 정수)

/

나눗셈

%

나머지

//

해당 연산자가 없음

**

거듭제곱

 

이미 대부분 전에 소개한 글에서 다루었지만, Python을 기준으로 //, %,** 그리고 문자열(리스트, 튜플)에 대한 곱셈과 덧셈을 좀 더 알아보겠습니다.

a = 16
b = 0.5
c = "Hello"
d = "World"
e = 5
print(a // e) # 몫 구하기
print(a ** b) # 거듭 제곱
print(c + d) #문자열 간 덧셈
print(c * e) # 문자열과 정수의 곱셈
-----------출력 결과----------------
3
4.0
HelloWorld
HelloHelloHelloHelloHello

참고로 0이하의 수로 문자열 등을 곱하면 결과는 0번 반복한 것과 같습니다.(예를 들어 "1234"*0는 ""를 나타냅니다.)

 

한편, 같은 숫자여도 여러가지 자료형이 존재합니다. 다른 숫자 자료형 사이 연산의 경우 적절히 형태가 변환되거나, 아니면 변환할 수 없다는 에러가 뜨게 됩니다. (이를 명시적으로 하는 방법에 대해서는 다다음 글에서 다루겠습니다.)

 

 예를 들어 Java에서는 다음 식이 불가능합니다. 이는 C에서는 가능한데요, 이는 암묵적인 형변환이 Java에서는 아래와 같은 방향으로는 이루어지지 않고, C에서는 이뤄지기 때문입니다.

--------------Java Style--------------
float num1 = 10f;
int num2 = num1/2;
-------------C/C++ Style--------------
float num1 = 10;
int num2 = num1/2;
--------------------------------------

Java는 오류가 나고, C/C++에서는 소수점 아래 수들을 버려서 대입하게 됩니다.(이는 Python도 마찬가지입니다.)

 

이와 같은 암묵적 형변환(또는 자동 형변환, 또는 Promotion)에 대해서 언어마다 고유의 규칙이 있습니다. 일반적으로 숫자에서 일반적으로 크기가 작은 자료형에서 큰 자료형으로 변환되는 것은 가능하지만, 큰 자료형에서 작은 자료형으로 내려오는 것은 C/C++에서만 가능합니다. 이는 오류의 원인이 될 수 있기 때문이기도 합니다. 일단 위의 예시처럼 데이터가 손실되기도 하고 아래와 같이 범위를 넘는 수를 대입하게 되면, 오버플로우(Overflow)나 언더플로우(Underflow)가 발생되어 의도치 않은 숫자를 표시하기 때문입니다.

 

int num1 = 10000;
char num2 = num1;
printf("%d",num2);
-------출력 결과-----------
16

(한편 Python3는 숫자 자료형이 정수, 실수 처럼 각 형태마다 자료형이 1개 씩이여서 크기 문제가 생길 일은 없어보입니다.)

 

 

대입 연산자는 말 그대로 대입하는 연산자입니다. 위의 산술 연산자와 같이 두 개항이 필요한 이항 연산자입니다. 우리가 아는 '='가 바로 대입 연산자입니다.  한편, 여기에 기능을 더해 산술연산과 대입을 동시에 하는 복합대입 연산자도 존재하는데요, 다음과 같은 연산자들이 있습니다.

연산자 의미
= 단순 대입
+= -= *= /= %=
(Python) //= **=

왼쪽에 언급된 어떤 연산자 ⊙에 대해서 =는 아래와 같이 표현할 수 있습니다.

num1⊙=num2       ⇔     num1 = num1 ⊙ num2

ex) num+=1  은 num = num + 1과 같습니다.     

물론 나중에 다룰 비트 연산자에 대해서도 복합 대입 연산자가 존재합니다. 방식은 위와 같습니다.

 

 

그리고 대입연산자에 대한 한가지 간과할 만한 사실을 짚어보자면, 연산자이므로 값을 반환할 수 있다는 점입니다. 마치 2+3이 5를 반환하듯이 말이죠. 이 경우 대입한 값을 반환합니다. 따라서 다음과 같은 식이 Java, C/C++, Python에서 가능합니다. (모두 a,b,c,d,e,f 변수에 10이 대입됩니다.)

-----------C/C++,Java Style---------------
int a,b,c,d,e,f;
a=b=c=d=e=f=10;
-----------Python Style-------------------
a=b=c=d=e=f=10

심지어는 아래 식도 가능합니다. 단, 아래와 같이 괄호가 있는 식은 Python에서는 오류가 납니다.

int a,b,c,d;
a=(b=(c=(d=5)));

대입 연산자도 덧셈과 같은 연산자라고 생각하면 이해가 되실 것입니다.

 


증감 연산자는 C/C++,Java에 존재하며 1만큼을 더하거나 뺄 때 필요합니다. 다음과 같은 형태가 있습니다.

연산자 의미 예시
++ , -- (Prefix) 1 증가(또는 감소) 단, 값을 평가하기 전 증가시킴. ++num, --num
++, -- (Suffix) 1 증가(또는 감소)단, 값을 평가한 후 증가시킴. num++, num--

두 가지 형태가 있는데 이는 증감 연산자도 역시 대입연산자 처럼 반환값이 있기 때문이라고 보면 편합니다. 단독으로 사용시에는 구분이 없지만, 수식에서는 다음과 같이 차이가 납니다.

 

int a,b;
a = 2;
b = 5;
cout<<(a++)*b<<" "<<a*b<<endl;
a = 2;
b = 5;
cout<<(++a)*b<<" "<<a*b<<endl;
---------------출력 결과--------------
10 15
15 15

suffix로 사용된 경우 해당 수식을 계산하는 동안에는 1을 더하지 않다가, 식을 평가하여 출력한 뒤 1을 더합니다. 즉, a++은 a를 반환하고 해당 수식이 끝나면, a+=1을 계산합니다.

 

prefix로 사용된 경우 해당 수식을 계산하기 직전에 1을 더합니다. 즉, ++a는 a+1을 반환하고, 동시에 a+=1을 계산합니다.

 

 

 

 

Comments