[Java] 기초 - 연산자, 제어문, 반복문(자바 메모리 구조)

이지연·2025년 12월 9일

개요

아래의 내용은 java_grammer 레파지토리 C01Basic 디렉터리에 저장되어있는 내용을 정리하였다.


연산자

산술 연산자 (사칙연산)

+, -, *, /, %는 다들 아는 바로 그 사칙연산임.

int n1 = 8;
int n2 = 3;
System.out.println("n1 * n2 = " + (n1 * n2)); // 24
System.out.println("n1 / n2 = " + (n1 / n2)); // 2
System.out.println("n1 % n2 = " + (n1 % n2)); // 2

정수끼리 나누면 몫만 나온다는 점 주의해야 함.
8 / 3은 2.666...이 아니라, 그냥 2임.


대입 연산자

= 을 기반으로 한 축약형 연산자들이 있음: +=, -=, *=, /=, %=

int n = 7;
n += 7; // 14
n -= 7; // 7
n *= 7; // 49
n /= 7; // 7
n %= 7; // 0

하나 주의할 점은

int n3 = 7;
n3 =- 3; // ❌ n3 -= 3 아님! => n3 = -3

이거 헷갈리는 사람 진짜 많음ㅋㅋㅋ


증감 연산자 (++ / --)

a++은 후위, ++a는 전위 증감 연산자임.

int b = 5;
int c = b++;
System.out.println(c); // 5 (먼저 대입 후 +1)
int d = ++b;
System.out.println(d); // 7 (먼저 +1 후 대입)

비교 연산자

==, !=, <, >, <=, >= 이런 것들.
조건문에서 자주 등장함.

int n1 = 10;
int n2 = 20;
System.out.println(n1 == n2); // false
System.out.println(n1 != n2); // true
if (n1 > n2) {
    System.out.println("n1이 n2보다 크다");
}

논리 연산자 (&&, ||, !)

조건 여러 개 조합할 때 필수.

int n1 = 10;
boolean b1 = !(n1 > 5 && n1 < 7); // false의 반대니까 true
System.out.println(b1);

비트 연산자 (&, |, ^, <<, >>)

이건 2진수 단위의 연산자임.
조금 생소하지만, 성능 관련 코드에서 종종 보임.

int n1 = 5; // 0101
int n2 = 4; // 0100
System.out.println(n1 & n2); // 4
System.out.println(n1 | n2); // 5
System.out.println(n1 << 1); // 10 (왼쪽으로 한 칸: *2)
System.out.println(n2 >> 2); // 1 (오른쪽으로 두 칸: /4)

제어문

if문 / else if문 / else문

조건에 따라 분기시키는 기본 구조.

String answer = "1234";
String answerInput = br.readLine();

if (answerInput.equals(answer)) {
    System.out.println("문이 열렸습니다.");
} else {
    System.out.println("비밀번호가 틀렸습니다.");
}

교통카드 예시

int money = Integer.parseInt(br.readLine());
if (money >= 10000) {
    System.out.println("택시를 타시오.");
} else if (money >= 3000) {
    System.out.println("버스를 타시오.");
} else {
    System.out.println("걸어가시오.");
}

삼항 연산자

한 줄로 깔끔하게 처리 가능.

String result = answerInput.equals(answer) 
    ? "문이 열렸습니다." 
    : "비밀번호가 틀렸습니다.";
System.out.println(result);

switch문

조건이 여러 개일 때 깔끔하게 표현할 수 있음.

int callNum = Integer.parseInt(br.readLine());
switch (callNum) {
    case 1:
        System.out.println("대출 업무입니다.");
        break;
    case 2:
        System.out.println("예금 업무입니다.");
        break;
    case 3:
        System.out.println("적금 업무입니다.");
        break;
    default:
        System.out.println("번호를 잘못 입력하셨습니다.");
        break;
}

반복문

while문 / do-while문

while문

조건이 참일 때 반복.
반드시 조건에 변화가 생기도록 해야 함.

int a = 0;
while (a < 10) {
    System.out.println("hello world " + a);
    a++;
}

do-while문

조건 안 봐도 무조건 한 번은 실행됨.

int a = 100;
do {
    System.out.println("hello world");
} while (a < 10);

for문

초기식, 조건식, 증감식이 한 번에 들어감.

for (int i = 0; i < 10; i++) {
    System.out.println("hello world");
}

짝수만 출력할 때는 continue를 이용하면 깔끔함.

for (int i = 0; i < 10; i++) {
    if (i % 2 != 0) continue;
    System.out.println(i);
}

향상된 for문 (Enhanced for문)

배열이나 리스트 같은 컬렉션을 빠르게 순회할 때 좋음.

int[] arr = {1, 3, 5, 7, 9};
for (int num : arr) {
    System.out.println(num);
}

다만, 값 변경은 원본에 반영되지 않음!


다중 for문 + 라벨문

구구단처럼 중첩 반복문 쓸 때 주로 사용.

for (int i = 2; i < 10; i++) {
    System.out.println(i + "단 입니다.");
    for (int j = 1; j < 10; j++) {
        System.out.println(i + "X" + j + "=" + (i * j));
    }
    System.out.println("================");
}

라벨문을 사용하면 원하는 반복문을 직접 제어 가능함.

loop1:
for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
        if (true) break loop1; // loop1 전체 종료
    }
}

cf) 배열을 출력할때 Arrays.toString()를 사용해야하는 이유

배열 출력과 메모리 구조 이해하기

배열을 출력하다 보면 이런 경험 한 번쯤 해봤을 거임

int[] arr = {1, 2, 3, 4};
System.out.println(arr);

출력 결과

[I@3f99bd52
  • 배열의 실제 값이 아니라 힙메모리에 저장된 위치(주소값)을 출력한 것임.
    그래서 Arrays.toString()을 써야 배열의 실제 내용이 나옴.
import java.util.Arrays;

int[] arr = {1, 2, 3, 4};
System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4]

그럼 왜 이런 일이 일어나는 걸까?
이는 자바의 메모리 구조와 관련이 있음.


자바 메모리 구조

자바 프로그램이 실행되면, JVM은 여러 영역에 데이터를 나눠서 저장함.
크게 보면 아래 세 가지 영역으로 구분돼 있음

메모리 영역저장되는 값설명
메소드 영역 (Method Area)클래스, static 변수, 메서드 정보빌드된 클래스 코드, static 변수 등 프로그램 전체에서 공유됨
스택 영역 (Stack Area)기본형 변수, 지역변수, 매개변수, 참조형 변수의 주소값메서드 호출 시마다 생성, 메서드 종료 시 자동으로 사라짐
힙 영역 (Heap Area)객체, 배열 등 참조형 변수의 실제 값new 연산자로 생성되는 데이터들이 저장

기본형 vs 참조형 변수

자바 변수는 크게 기본형(Primitive Type)과 참조형(Reference Type)으로 나뉨.

구분저장 대상저장 위치예시
기본형 변수실제 값 자체스택 영역에 저장int a = 10;
참조형 변수힙 영역에 저장된 값의 주소스택에는 주소값만 저장int[] arr = {1,2,3};

즉, 이런 구조임

스택 영역                    힙 영역
-----------                ---------------
arr ───────────────▶   [1, 2, 3]

arr은 스택에 있고, arr이 가리키는 실제 데이터 [1, 2, 3]은 힙에 존재함.
그래서 System.out.println(arr)을 하면 주소값만 보이는 것임.

이걸 사람이 보기 좋게 변환해주는 게 바로 Arrays.toString() 같은 메서드임.
이건 내부적으로 배열의 값을 순회하면서 문자열로 만들어줌.

핵심 정리

  • 기본형 변수: 스택에 저장, 값 자체 출력 가능.
  • 참조형 변수(배열, 객체 등): 힙에 저장, 스택에선 주소만 들고 있음.
  • 기본형은 바로 출력되지만, 참조형은 주소를 출력하므로 toString() 같은 메서드 필요.
  • Arrays.toString()은 배열 요소를 문자열로 만들어 사람이 읽을 수 있도록 변환해줌.

자바 변수의 유효 범위

{}

       int num1 = 10;
        if(true){
            num1 = 20;
            int num2 = 30;
        }
        // 하위 영역의 불록(줄괄호)에서 정의된 변수는 상위 블록에서는 접근 불가
        num2 = 40;

        // for문은 사용했던 변수명을 for문이 끝난 이후에 또 다른 for문에서 재선언이 가능
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
        }
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
        }
        
profile
Eazy하게

1개의 댓글

comment-user-thumbnail
2025년 12월 11일

다중 for 문을 조심해야하는 이유 :
다중인격이 될 수도 있습니다. 무척 조심해야 합니다.

답글 달기