7. Java 강좌, 연산자 4

2015.02.12 21:41
저자 : Tailer

연산 시 주의사항 2



class calc1

{

public static void main(String[] args)

{

char a1 = 'a';   //  a1에는 문자 'a'의 코드값인 97이 저장된다.

char a2 = a1;   //  a2에는 a1의 값이 저장된다.

 

int i = a1 + 1;   //  i에는 97 + 1 이 int형태로 저장된다.

char a3 = (char)(a1 + 2);   // 형변환을 해주지않으면 int로 저장되기에 컴파일시 오류가 난다.

a2++;   //  형변환을 해주지않아도 된다.

 

System.out.print(i + "\t" + a2 + "\t" + a3);

}

}

 

위에서 a1은 문자 'a'가 저장됩니다.


여기서 a는 ASCII 코드 값으로 97을 말하는데요,

char a1은 ASCII 코드 값인 97이 저장이 됩니다.

그리고 char a2는 a1에 있는 값 97이 저장 되겠죠.


물론 char라는 타입을 가지고 있기 때문에 자체는 문자 'a'로 인식 하고 있죠.


그런데 여기서 int형 변수 i에 a1 + 1을 하게 되면 char에 들어있던 a는 int 형 97로 변환되고 +1을 하면서 int i는 98이 되어버립니다.

char a3은 (char)의 형태로 연산을 했기 때문에 (a1 + 2)를 연산 하더라도 ASCII 값 99가 되고 c가 출력됩니다.


a2++의 경우에는 자기 자신에 +1을 해주기 때문에 자연스럽게 char 형으로 연산을 하게 되고, 98번인 b가 출력됩니다.


위와같이 int 이하의 변수 타입을 사용하는 경우에는 연산 시 int로 변환되는 것을 주의해야합니다.



class calc2

{

public static void main(String[] args)

{

char a1 = 'a';

//         char a2 = a1 + 1;   // 컴파일에러발생

char a3 = 'a' + 1;  // 정상작동

 

System.out.print(a3);

}

}

 

위의 코드를 실행하면 int보다 작은 형태의 변수는 int로 변환되는 것이 맞지만,

주석 처리된 a2는 에러가 발생하고 a3은 에러가 발생하지 않습니다.


그 이유는 'a' + 1 은 리터럴 간의 연산이기 때문입니다.

(여기서 리터럴이란 변수를 선언할 때 사용하는 수들 'a', 10 등과 같이 변수, 상수 등을 초기화 할 때 적는 값들을 말합니다.)


변수가 아닌 상수나 리터럴간의 연산은 프로그램 실행 중에 변하는 값이 아니기 때문에,

소스코드를 컴파일 시 컴파일러가 먼저 계산하고 리터럴간의 연산을 먼저 실행합니다.

이로써 코드가 더욱 효율적으로 변하게 됩니다.

 

 

이처럼 'a' + 1;과 같은 연산은 리터럴간의 연산을 미리 실행하여 char c = 'b';라고 적은 것과 같은 결과를 나타냅니다.

int i = 100 * 100 또한 두 개의 100이 리터럴이므로 리터럴간의 연산을 먼저 실행해서 int i = 10000;이라고 적은 것과 같은 결과를 보여줍니다.


만약 수식에 변수가 들어있는 경우에는 프로그램 사용 도중 값이 변할 수 있기 때문에 컴파일러가 미리 계산을 할 수 없습니다.

그래서 형변환이 필요하고, 형변환을 하지 않을 경우 오류가 생기게 됩니다.

 

리터럴과 상수에 대해서 더 자세히 설명하고 넘어가겠습니다.


String name = "kurien";

int i = 100;

 

위에서 name과 i는 변수입니다. 이런 변수들은 연산 도중 언제든지 변할 수 있습니다.

여기서 "kurien"은 문자열 리터럴이고, 100은 숫자형 리터럴입니다.


그리고 상수란 변수와 같이 초기화를 하지만 초기화 이후에는 더 이상 변할 수 없습니다.

java에서는 아래와 같이 표현하죠


final String name = "kurien";

final int i = 100;


위와같이 상수를 선언하면 변수와는 달리 i = 30; 과 같이 값을 재할당 해줄 수 없습니다.

값을 바꾸려고 하더라도 컴파일 시 에러가 발생하죠.


위의 예제에서는 char a2 = a1 + 1; 는 컴파일 시 에러가 발생한다고 했었는데요,

이것을 상수 변경 한 후 테스트 해보겠습니다.


class calc3

{

public static void main(String[] args)

{

final char a1 = 'a';

char a2 = a1 + 1;

System.out.print(a2);

}

 

이전의 예제와는 달리 이번에는 덧셈 연산을 해도 int 로 형변환이 되지않고 오류없이 작동하는것을 볼 수 있습니다.

상수 또한 변하지 않는 수이기 때문에 상수와 리터럴간의 연산으로 컴파일 시 연산이 끝났기 때문이죠.


이러한 연산자의 성질을 이용해서 아래와같이 소수점 몇자리를 버리는 연산도 가능합니다.



class calc4

{

public static void main(String[] args)

{

float pi = 3.141592f;

float shortpi = (int)(pi * 100) / 100f;

System.out.print(shortpi);

}

}

 

위의 코드에서는 int 형 변수 타입이 소수점 아래의 모든 숫자를 버리는 성질을 이용했습니다.


pi * 100 의 연산결과는 314.1592인데, (int)로 형변환을 했기 때문에 소수점 아래 자리를 모두 버리게 됩니다.

그러므로 연산 값은 314만 남게 되는데, 그 후 100f로 나눠줬기 때문에 3.14로 값을 저장하게 됩니다.

'Programming > Java' 카테고리의 다른 글

8. Java 강좌, 연산자 5  (0) 2015.02.16
7. Java 강좌, 연산자 4  (0) 2015.02.12
6. Java 강좌, 연산자 3  (0) 2015.02.10
5. Java 강좌, 연산자 2  (2) 2015.02.08
4. Java 강좌 연산자 1  (2) 2015.02.02
3. Java 강좌, 변수(Variable) 2  (0) 2015.01.29