Develop growth diary/JAVA

자바 기반 구조적 프로그래밍 02 - 연산자와 연산식

pponyo 2022. 9. 28. 16:38
728x90
반응형

 

연산자 우선순위
산술연산자 > 비교연산자 > 논리연산자 > 대입연산자

 

JAVA 프로그램 내 다양한 연산자가 존재하고, 연산자 간의 우선순위가 존재한다.

기존에는 단순하게 산술연산에서의 우선순위만 생각하고 적용했지만

연산자 우선순위를 비교하고나니 결과값이 출력되는 원리를 훨씬 쉽게 이해할 수 있었다 :)

 

산술연산자는 왼쪽에서 오른쪽 순으로 연산

대입연산자는 오른쪽에서 왼쪽 순으로 연산

 

산술연산자가 우선순위에서 가장 먼저, 대입연산자가 가장 마지막이라는 점은 꼭 기억할 것!

 

증감연산자 ++
전위형 ++a  / 후위형 a++

 

증감연산자에서 전위형, 후위형의 구분은 기존에 가장 이해가 어려웠던 부분 중 하나였다.

단순하게 생각하면 증감을 변수 사용 전에 적용하고, 변수 사용 후에 적용하는 방식인데,

제대로 이해를 하지않으면 '출력했을 때의 결과값이 오류가 아닌가...'라고 생각되어질 때가 많았다ㅠㅠ

 

전위형 증감연산자는 해당되는 행에서 즉시 증감이 이루어지고,

후위형 증감연산자는 해당되는 행에서는 증감이 이루어지지않고, 다음행에서부터 증감이 이루어진다.

 

실제 후위형 증감연산을 변수 y에 적용(y++)하였을 때

 Line 8에서는 증감이 이루어지지않아 '10'의 값이 그대로 출력되었지만

Line 11에서는 1이 증감되어 '11'의 값으로 출력되는 것을 직접 확인 할 수 있었다.

 

 

논리부정연산자 !

 

논리부정연산자는 정반대되는 의미(값)라고 생각하면 간단하지만

boolean 타입에 논리부정연산을 적용하여 토글 기능을 수행할 수 있음을 확인하였다.

 

나머지연산자 %

 

나머지연산자에서는 피연산자가 음수인 경우 피연산자를 절대값으로 변환하여 연산을 수행하여

연산자가 양수일 때와 음수일 때 결과값이 다르게 출력되는 것을 확인할 수 있었다.

 

산술연산자에서 나누기연산을 할때와는 다르게 적용되어 헷갈리기 쉬운 부분이기 때문에 기록!

 

Overflow

 

Overflow의 개념은 지난 시간에 익혔지만 메소드에서의 활용을 알아보았다.

int 타입끼리의 연산에서 int 타입의 허용범위를 초과한 경우 결과값은 쓰레기값이 된다.

(그 외  크기가 작은 단일 데이터 타입끼리의 모든 연산에서 동일하게 적용된다! boolean, char 타입 제외)

 

결과값에 대한 변수를 long 타입에 대입하더라도 int 타입끼리의 연산 결과는 int 타입이기 때문에

이미 계산결과가 쓰레기값이 된 상태에서 long 타입에 대입되어도 결과는 달라지지 않는다.

 

따라서 강제타입변환을 통해 long 타입으로 결과값을 올바르게 출력하기 위해서는

피연산자 중 하나의 타입을 long으로 강제변환하여 연산하고 대입하거나

최초에 피연산자의 타입을 long 타입으로 선언하여 연산하면 long 타입으로 출력이 가능하다.

 

메소드 호출  (feat. 디버깅)

 

메소드의 작성과 호출에서는 매개변수를 이용하여 메소드를 작성하고, 호출하는 것을 복습하였다!

 

메인메소드에서 String 타입의 변수 greeting에 "안녕하세요?"라는 문자열 데이터를 할당하고,

별도의 proceed 메소드 매개변수 message에 메인메소드 내 greeting의 데이터를 대입하여 출력되도록 하였다.

 

기존에는 개념을 익히고 단순히 메소드를 작성하고 호출하는 것에 그쳤다면

이번 수업에서는 디버깅을 통해 실행되고 출력되는 과정까지를 직접 확인할 수 있었다.

 

디버깅(Debugging) 결과

 

출력되는 순서는 Line 10 → 13 → 14 → 19 → 20 → 15 순서인데,

먼저 Line 9에서 메인메소드가 가장 먼저 실행이 되면 Line 10의 실행문을 출력하고,

Line 12에서 변수 greeting에 "안녕하세요?"라는 문자열 데이터를 저장한 다음

Line 13에서 다시 실행문을 출력하게 된다.

 

그런 다음 Line 14에서 proceed 메소드를 호출하면 Line 18이 수행되고 ,

greeting의 데이터값을 proceed 메소드에 대입하여 message에 "안녕하세요?"가 저장된다.

다음으로 Line 19에서 실행문이 출력되고, Line 20에서 message에 저장된 "안녕하세요?"가 출력되고나면

Line 22에서 proceed 메소드를 벗어나 다시 메인메소드로 돌아간다.

 

proceed 메소드를 벗어나면 Line 14의 proceed 호출 구문이 종료되고,

Line 15의 실행문이 출력되고 Line 16에서 메인메소드가 종료된다.


메소드 호출
반환 타입과 매개변수가 없는 경우

 

반환 타입과 매개변수가 모두 없는 경우에는 public[또는 private] static void '변수명'() 구문을 활용하여

메인메소드에서 호출할 수 있고, 생성된 메소드 내의 실행문을 출력한다.

 

출력순서 Line 6 → 14 → 23 → 24 → 8 → 19 → 10

 

메소드 호출
매개변수는 없고 반환 타입은 있는 경우

 

반환 타입은 있지만 매개변수는 없는 경우 public[또는 private] static 반환 타입 '변수명'() 구문을 활용하여

메인메소드에서 호출할 수 있고, 생성된 메소드 내의 반환값을 메인메소드로 반환한다.

 

출력순서 Line 6 → 9 → 10

 

getMessage 메소드 내에서는 출력을 위한 실행문이 존재하지 않으므로

str 값만을 반환하여 메인메소드에서 실행문으로 출력하여 확인할 수 있다.

 

메소드 호출
반환 타입과 매개변수가 모두 있는 경우

 

반환 타입과 매개변수가 모두 있는 경우 public[또는 private] static 반환 타입 '변수명'(반환 타입 a, 반환 타입 b) 구문을 활용하여 메인메소드에서 호출할 수 있고, 원하는 값을 메인메소드로 반환하여 출력할 수 있다.

 

메인메소드에서 호출할 때 매개변수 타입과 동일한 파라미터를 입력하여야 대입 및 출력이 가능하다.

 

 

결과값 Overflow 주의
정수의 덧셈에서 두 정수의 부호가 같을 때 발생할 수 있는 Overflow 살펴보기

 

입력된 값을 연산하였을 때 int(해당 데이터 타입)의 범위를 넘어서면 overflow가 발생한다.

이런 경우를 대비하여 예외가 발생하였을때 원하는 실행문을 출력할 수 있다.

 

수업시간에 작성한 예시를 토대로 살펴보면 safeAdd메소드를 생성하고,

allPositive에는 피연산자 모두 양수인 경우를, allNegative에는 피연산자 모두 음수인 경우를 저장한다.

(두 피연산자의 부호가 같을 때에만 overflow가 발생하기 때문!)

 

다음으로 boolean 타입으로 결과값이 true이면 overflow가 발생하는것으로 간주할 수 있도록

Integer.MAX_VALUE 값과 Integer.MIN_VALUE 값을 활용하여 maxBounded 와 minBounded를 선언한다.

 

두 피연산자가 모두 양수일 때의 합이 Integer.MAX_VALUE 값을 넘지 않는지,

두 피연산자가 모두 음수일 때의 합이Integer.MIN_VALUE 값을 넘지 않는지 확인하기 위해

비교연산자를 활용하여 값을 알아볼 수 있다.

 

이 때 left + right의 값이 overflow가 되면 올바른 값이 아니므로 정확한 비교연산이 불가능하기 때문에

두 피연산자 중 한 가지를 이항하여 확인해 볼 수 있다.

 

 확인 결과 maxBounded 또는 minBounded가 둘 중 하나라도 결과값이 true인 경우

ArithmeticException(예외)를 던져 메인메소드에서 실행문을 출력하고,

maxBounded 또는 minBounded의 결과값이 모두 false인 경우 left + right 값을 메인메소드로 반환한다.

 

다시 메인메소드 내에서 살펴보면 try 구문에서 예외가 발생할 수 있는 코드(파라미터 입력)를 작성하고,

해당 예외가 발생한 경우 예외발생 시 처리 결과를 불러와 실행하고 출력한다.

 

 


오늘 수업에서 기억해야할 가장 중요한 점!

디버깅을 통해 실행 과정과 출력 순서를 직접 확인하면 이해가 훨씬 쉽다 :)

디버깅 할때에는 각 블록의 시작을 breakpoint로 설정하여 수행한다.

 

728x90
반응형