다라다라V
article thumbnail
728x90
반응형

스코프 1 - 지역 변수와 스코프

  • 변수는 선언한 위치에 따라
    1. 지역 변수
    2. 멤버 변수 (클래스 변수, 인스턴스 변수)

지역 변수

  • 특정 지역에서만 사용할 수 있는 변수
    • 특정 지역을 벗어나면 사용할 수 없음
  • 지역 = 코드가 선언된 코드 블럭 {}
  • 지역변수는 코드가 선언된 코드 블록 내에서만 생존
    • 이후에는 접근할 수 없음
package scope;

public class Scope1 {
    public static void main(String[] args) {
        int m = 10; // m 생존 시작
        if (true) { // x 생존 시작
            int x = 20;
            System.out.println("if m = " + m);
            System.out.println("if x = " + x);
        } // x 생존 종료
        System.out.println("main x = " + x);
        System.out.println("main m = " + m);
    } // m 생존 종료
}

/Users/ryujiye/Inflearn/Inflearn Java/java-start/src/scope/Scope1.java:11:42
java: cannot find symbol
  symbol:   variable x
  location: class scope.Scope1
  • 컴파일 오류 발생

스코프

  • 변수의 접근 가능한 범위를 스코프(Scope)
  • 생존 범위가 맞아야 변수에 접근할 수 있음

스코프 2 - 스코프 존재 이유

  • 스코프가 필요한 이유
    • 비효율적인 메모리 사용
      • 불필요한 메모리가 낭비됨
      • 코드 블록 내부에 임시로 사용되는 변수를 선언하면 종료 시점에서 메모리 제거 가능
      • 더 효율적으로 메모리 사용
    • 코드 복잡성 증가
      • 좋은 코드는 군더더기 없는 단순한 코드
      • 블록 안에 선언하면 사용한 뒤에 변수 하나를 줄일 수 있음
      • 스코프가 불필요하게 넓어지는 경우 실무에서 복잡함

while문 vs for문 - 스코프 관점

  • 변수 i 와 같이 for 문 안에서만 사용되는 카운터 변수가 있다면
    • while 문 보다는 for 문을 사용해서 스코프의 범위를 제한하는 것
    • 메모리 사용과 유지보수 관점에서 더 좋음

정리

  • (지역) 변수는 꼭 필요한 범위로 한정해서 사용하기
    • 변수의 스코프는 꼭 필요한 곳으로 한정해서 사용
    • 메모리를 효율적으로 사용하고 더 유지보수하기 좋은 코드

좋은 프로그램은 무한한 자유가 있는 프르그램이 아니라 적절한 제약이 있는 프로그램

  • 무한한 자유 = 무한한 버그

형변환1 - 자동 형변환

형변환

작은 범위에서 큰 범위로의 대입은 허용한다

  • 작은 범위에서 큰 범위로는 갈 수 있음
    • int → long → double
  • 큰 범위에서 작은 범위는 문제가 발생
    • 소수점 버림
    • 오버플로우
package casting;

public class Casting1 {
    public static void main(String[] args) {
        int intValue = 10;
        long longValue;
        double doubleValue;

        longValue = intValue; // int->long
        System.out.println("longValue = " + longValue);

        doubleValue = intValue; // int -> double
        System.out.println("doubleValue = " + doubleValue);

        doubleValue = 20L; //long->double
        System.out.println("doubleValue2 = " + doubleValue);
    }
}

  • 자바는 기본적으로 같은 타입의 값을 대입
  • 작은 범위에서 큰 범위로의 대입도 허용
    • 큰 그릇은 작은 그릇의 내용물을 담을 수 있다

자동 형 변환

  • 대입하는 형(타입)을 맞춰야함
    • 개념적으로는 데이터타입이 바뀜
//intValue = 10
doubleValue = intValue
doubleValue = (double) intValue // 형 맞추기
doubleValue = (double) 10 //변수 값 읽기
doubleValue = 10.0 //형 변환
  • 작은 범위 → 큰 범위는 자동으로 이루어짐
    • 개발자가 직접 형 변환할 필요가 없음
    • 자동 형변환, 묵시적 형변환

형변환2 - 명시적 형변환

큰 범위에서 작은 범위 대입은 명시적 형 변환이 필요하다

  • java: incompatible types: possible lossy conversion from double to int
    • double → int 시 컴파일 오류
    • 단순히 대입하려고 하면 오류가 발생함

형변환

package casting;

public class Casting2 {
    public static void main(String[] args) {
        double doubleValue = 1.5;
        int intValue = 0;

        intValue = (int) doubleValue; // 형변환
        System.out.println(intValue);
    }
}
  • 명시적 형 변환
    • = 캐스팅
    • 개발자가 직접 형변환 코드를 입력함
  • 변경하고 싶은 데이터 타입을 괄호( )를 사용해 명시적으로 입력

명시적 형변환 과정

//doubleValue = 1.5
intValue = (int) doubleValue;
intValue = (int) 1.5; //doubleValue에 있는 값을 읽는다.
intValue = 1; //(int)로 형변환 한다. intValue에 int형인 숫자 1을 대입한다.
  • 형변환은 안의 값이 변경되거나 타입이 변경되는 것은 아님
    • 읽은 값을 형변환 하는 것
  • 변수의 값은 대입연산자= 를 사용하는 경우에만 변경되는 것
    • 자바에서 유일하게 값을 변경하는 것은 대입 연산자뿐

형변환과 오버플로우

package casting;

public class Casting3 {
    public static void main(String[] args) {
        long maxIntValue = 2147483647; //int 최고값
        long maxIntOver = 2147483648L; //int 최고값 + 1(초과)
        int intValue = 0;

        intValue = (int) maxIntValue; // 형변환
        System.out.println("maxIntValue casting = " + intValue); // 2147483647

        intValue = (int) maxIntOver; // 형변환
        System.out.println("maxIntOver casting = " + intValue); // -2147483648
    }
}

  • 초과 범위는 L 을 붙여서 long 형을 사용함
  • long → int는 오류가 발생하는 것을 확인
    • 시계가 한 바퀴를 돈 것 처럼 처음부터 다시 시작
    • int의 가장 작은 수가 출력됨
  • 오버플로우가 발생
    • 사이즈를 늘려서 오버플로우 문제를 해결
  • 오버플로우가 발생하는 것 자체가 이미 큰 문제

계산과 형변환

package casting;

public class Casting4 {
    public static void main(String[] args) {
        int div1 = 3 / 2;
        System.out.println("div1 = " + div1); // 1

        double div2 = 3 / 2;
        System.out.println("div2 = " + div2); // 1.0

        double div3 = 3.0 / 2;
        System.out.println("div3 = " + div3); // 1.5

        double div4 = (double) 3 / 2;
        System.out.println("div4 = " + div4); // 1.5

        int a = 3;
        int b = 2;
        double result = (double) a / b;
        System.out.println("result = " + result); // 1.5
    }
}

계산 기억

  1. 같은 타입끼리의 계산은 같은 타입의 결과를 낸다
    • int + int 는 int를 double + double 은 double의 결과가 나온다.
  2. 서로 다른 타입의 계산은 큰 범위로 자동 형변환이 일어난다
    • int + long은 long + long으로 자동형 변환
    • int + double 은 double + double로 자동형 변환
int div1 = 3 / 2; //int / int
int div1 = 1; //int / int이므로 int타입으로 결과가 나온다
 double div2 = 3 / 2; //int / int
double div2 = 1; //int / int이므로 int타입으로 결과가 나온다.
double div2 = (double) 1; //int -> double에 대입해야 한다. 자동 형변환 발생
double div2 = 1.0; // 1(int) -> 1.0(double)로 형변환 되었다.
double div3 = 3.0 / 2; //double / int
double div3 = 3.0 / (double) 2; //double / int이므로, double / double로 형변환이 발생한
다.
double div3 = 3.0 / 2.0; //double / double -> double이 된다.
double div3 = 1.5;
double div4 = (double) 3 / 2; //명시적 형변환을 사용했다. (double) int / int
double div4 = (double) 3 / (double) 2; //double / int이므로, double / double로 형변
환이 발생한다.
double div4 = 3.0 / 2.0; //double / double -> double이 된다.
double div4 = 1.5;

정리

  • 형변환
    • int → long → double
    • 작은 범위에서 큰 범위로는 대입 가능
      • = 묵시적 형변환 , 자동 형변환
    • 큰 범위에서 작은 범위의 대입은 문제가 발생
      • 명시적 형변환을 사용
      • 소수점 버림, 오버플로우 문제 발생
    • 연산과 형변환
      • 같은 타입은 같은 결과
      • 서로 다른 타입의 계산은 큰 범위로 자동 형변환
반응형

'코딩언어 > [인프런] JAVA 입문' 카테고리의 다른 글

5. 반복문  (0) 2024.05.12
4. 조건문  (0) 2024.05.01
3. 연산자  (0) 2024.05.01
2. 변수  (0) 2024.04.28
1. Hello World  (0) 2024.04.28
profile

다라다라V

@DaraDaraV

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!