주인장의 프로그래밍 개발 공부방

[Chapter 3 조건문] 4. 중첩 조건문 본문

프로그래밍 기본 지식/Chapter 3 조건문

[Chapter 3 조건문] 4. 중첩 조건문

거신 2019. 7. 1. 16:28

우리가 앞서 조건문에 대해서 자세히 알아봤는데

이번에 알아볼 내용은 바로 중첩으로 조건문을 사용하는 것이다.

 

목표 : 중첩으로 조건문을 사용할 수 있다.

 

1. 중첩 조건문으로 사용

 

이미 이전에 만난 적이 있었다.

if문을 알아볼 적에 if문의 응용_2라고 하는 부분이었는데

if문 안에 또 다른 if문을 넣어서 작성하는 것이었다.

그 때의 예시를 다시 들고와서 알아보자.

 

예시1)

Scanner sc = new Scanner(System.in);
int score = 0;
score = sc.nextInt();

if (score >= 90 && score <= 100) {
	if (score >= 97) {
		System.out.println("A+입니다.");
	}
	else if (score <= 93) {
		System.out.println("A-입니다.");
	}
	else {
		System.out.println("A입니다.");
	}
}
sc.close();

위와 같은 예시가 있었는데 if문 안에 새로운 if문을 집어넣어서

세부 조건을 선택할 수 있도록 작성한 것이다.

예시의 결과를 예상해보자면 score가 90이상 100이하의 정수일 때

if문이 실행될 것이고 외부 if문 안으로 들어가서 또 다시 조건을 확인할 것이다.

여기에서 score가 만약 97이상이면 "A+입니다."가 출력될 것이고

93이하면 "A-입니다."

그 외의 숫자라면 "A입니다."가 출력될 것이라고 예상할 수 있다.

 

위와 같이 if문 안에서 새로운 조건을 지정해서

좀 더 세부적인 조건을 만족시켜서 출력할 수 있다는 점이다.

중첩은 제한이 없으며 할 수 있다면 무한정 중첩시킬 수 있다.

(하지만 그렇게까지 할 프로그램은 아마 세상에 존재하지 않을 것이라 생각한다.)

 

그렇다면 if만 가능할까?

switch문도 물론 가능하고

심지어 혼용해서 사용할 수도 있다.

if문 안에 switch문 또는 switch문 안에 if문도 전혀 문제없다.

자신이 프로그램을 작성하면서 좀 더 효율적인 명령어를 사용하면 되는 것이다.

 

2. 중첩 조건문의 구조

 

이전에도 잠깐 살펴봤던 내용인데

이번에 조금 더 자세하게 알아보도록 하자.

알고보면 굉장히 간단한 내용인데

처음 접하면 꽤나 복잡하게 생각할 수도 있으니

한 번 짚고 넘어가려고 한다.

 

같은 예시를 계속 쓰면 재미가 없으니

새로운 예시를 만들어보자.

 

예시2)

Scanner sc = new Scanner(System.in);
System.out.println("메뉴를 선택하세요.");
System.out.println("1.로그인 2.회원가입 3.종료");
System.out.print("번호 : ");
int menu = sc.nextInt();
switch(menu) {
case 1:
	System.out.println("로그인 메뉴입니다.");
	System.out.println("아이디를 입력하세요.");
	System.out.print("아이디 : ");
	String id = sc.next();
	
	if(id.equals("abc")) {
		System.out.println("비밀번호를 입력하세요.");
		System.out.print("비밀번호 : ");
		String pw = sc.next();
		
		if(pw.equals("1234")) {
			System.out.println("로그인이 되었습니다.");
		}
		else {
			System.out.println("비밀번호를 틀렸습니다.");
		}		
	}
	else {
		System.out.println("아이디가 존재하지 않습니다.");
	}		
	break;
case 2:
	System.out.println("회원가입 메뉴입니다.");
	break;
case 3:
	System.out.println("시스템을 종료합니다.");
	break;
default:
	System.out.println("잘못된 메뉴를 선택했습니다.");
}
sc.close();

재밌는 코드를 작성하다보니 코드가 길어졌다.

거기다 조건문이 중첩되어 있다보니

조금 복잡해 보일 수도 있는데 찬찬히 살펴보면

별거 아니니 차근차근 해석해보자.

 

일단 먼저 알 수 있는 것은

예시2에서는 조건문이 무려 3개가 포함되어 있는 코드가 되겠다.

첫 번째로 가장 외곽에 있는 switch문

case 1: 안에 바깥쪽 if문,

그 안에 안쪽 if문이 포함되어 있다.

 

먼저 외곽에 있는 switch문의 역할을 살펴보자면

사용자가 1 ~ 3번까지의 메뉴 중에서 하나의 번호를 선택할 것이다.

선택한 번호를 가지고 switch에서 판단하게 된다.

일단 우리는 조건문을 봐야하기 때문에

메뉴를 1번으로 선택한다고 가정해보자.

 

1을 입력하고 진행하면

다시 한 번 조건문이 등장한다.

두 번째 조건문인 바깥쪽 if문은 아이디를 입력했을 때

동일한 아이디를 입력했는지 확인게 되고

만약 동일한 아이디를 입력했다면 그 안에 있는 안쪽 조건문을 만나게 될 것이고

비밀번호를 입력하라는 메시지를 만나게 된다.

 

다시 정리하자면

switch안에 if문, 그리고 그 안에 또 다른 if문이 들어있는 구조가 되겠다.

 

구조)

그림으로 그리면 이런 구조라는 것도 알 수 있을 것이다.

여기에는 if문 안에 switch문이 들어갈 수도 있고

switch문 안에 새로운 switch문이 또 들어가도 상관이 없다.

그 부분은 개인이 생각해서 좀 더 효율적인 조건문을 선택해서 작성하면 되겠다.

 

3. 중첩 조건문의 범위 - 변수의 사용 범위

 

이렇게 조건문을 무려 3개씩이나 사용해서 프로그램을 작성할 수도 있다.

당연히 세부조건이 다양해진다면 필요에 따라서 조건문을

여러개를 사용하는게 효과적이다.

그렇기 때문에 우리들은 프로그램을 작성할 때

대략적이 아니라 더욱 더 세밀한 프로그램으로 작성할 수 있는 것이다.

 

그런데 여기에서 하나 확인해야하는 부분이 하나 있다.

바로 조건문 안에서 선언된 변수들이 그 것이다.

이 부분은 사실 다른 부분에서 더 자세하게 알아볼 내용이긴 하지만

그리 어렵진 않기 때문에 여기서 잠깐 짚고 넘어가도록 하자.

 

변수의 사용 범위라고 했는데

변수라는 녀석은 어느 지역에서 선언이 되는가에 따라서 사용할 수 있는 범위가 달라지는데

그 부분을 모르는 상태에서 쓰다보면

분명히 변수를 선언했는데 사용할 수 없는 경우가 발생하기 마련이다.

 

일단 프로그래밍에서는 { } (중괄호)로 구역을 표시한다.

그리고 그 안에서 선언된 변수는 해당 { } 안에서는 어디서든 사용할 수 있다.

반대로 해당 { } 밖에서는 사용할 수 없다.

참고로 변수의 초기화(값을 저장하는 것)가 아니라

변수를 선언했다라는 점을 잊지말자.

다시 말해 int i = 0;과 같이 타입 지정과 변수명을 지정한 것을 말하는 것이다.

i = 0;과 같이 단순히 값을 저장하는, 초기화를 하는 것을 말하는게 아니다.

 

위의 예시2로 다시 알아보자.

 

예시2)

Scanner sc = new Scanner(System.in);
System.out.println("메뉴를 선택하세요.");
System.out.println("1.로그인 2.회원가입 3.종료");
System.out.print("번호 : ");
int menu = sc.nextInt();
switch(menu) {
case 1:
	System.out.println("로그인 메뉴입니다.");
	System.out.println("아이디를 입력하세요.");
	System.out.print("아이디 : ");
	String id = sc.next();
	
	if(id.equals("abc")) {
		System.out.println("비밀번호를 입력하세요.");
		System.out.print("비밀번호 : ");
		String pw = sc.next();
		
		if(pw.equals("1234")) {
			System.out.println("로그인이 되었습니다.");
		}
		else {
			System.out.println("비밀번호를 틀렸습니다.");
		}		
	}
	else {
		System.out.println("아이디가 존재하지 않습니다.");
	}		
	break;
case 2:
	System.out.println("회원가입 메뉴입니다.");
	break;
case 3:
	System.out.println("시스템을 종료합니다.");
	break;
default:
	System.out.println("잘못된 메뉴를 선택했습니다.");
}
sc.close();

현재 변수는 Scanner를 제외하고

int타입의 menu,

String타입의 id, pw가 선언되어 있다.

일단 int menu는 main() 상에서 선언되어 있고

String id는 switch문 안에 case 1:에,

String pw는 switch문 안에 case 1: 안에 바깥쪽 if문에 선언되어 있다.

 

그림으로 살펴보자면 이런 형태가 된다.

따라서 menu는 현재 소스코드에서 main() 안이라면 어디에서든 사용이 가능하지만

id의 경우에는 case 1: 안에서만 사용이 가능하다.

case 1:을 벗어나 case 2:나 case 3:에서는 사용이 불가능한 것이다.

그리고 pw는 바깥쪽 if문에 선언이 되어 있기 때문에 바깥쪽 if문 안에서는

어디서든지 사용할 수 있다.

그렇기 때문에 안쪽 if문에서도 pw.equals("1234")와 같이 사용이 가능한 것이다.

하지만 바깥쪽 if문을 벗어난 case 1: 안에서는 사용할 수가 없다.

당연한 것이지만 case 2:, case 3:에서는 절대 사용할 수가 없다.

 

나중에 전역 변수(또는 필드, 멤버 변수)와 지역 변수에 대해서 알아볼 기회가 있을텐데

그 때 더 자세하게 알아보도록 하자.

지금은 이렇게만 이해해도 된다.

 

그런데 만약 여기에서 

switch(menu) {

String id = sc.next();

case 1:

라고 선언이 되었다면 여기에서 id는 case 1: 뿐만 아니라

case 2:, case 3:에서도 전부 사용이 가능하다.

 

그리고 변수를 사용할 수 있는 범위가 지정되어 있기 때문에

다른 { }(지역)에서 똑같은 변수명으로 새롭게 선언을 하는 것도 가능하다.

예를 들면 현재 case 1:에서 String id라고 선언이 되어 있는데

case 2:에서도 String id로 선언을 해도 에러가 발생하지 않는다는 것이다.

그 이유는 case 1:과 case 2:의 id는 별개의 변수가 되기 때문이다.

하지만 안에 속해 있는 범위에서는 새롭게 선언이 불가능하다.

가령 case 1:에서 String id로 선언을 했는데

case 1: 안의 if문에서 String id로 선언을 하면 에러가 발생하게 된다.

위의 두 id는 같은 녀석이기 때문이다.

 

4. 마무리

 

중첩 조건문조건문 안에 또 다른 조건문이 들어있는 형태가 되겠다.

if문으로만 중첩으로 사용할 수도 있고

switch문으로만 중첩으로 사용할 수 있으며

if문과 switch문을 혼용해서 중첩 사용도 가능하다.

그 부분은 개발자가 좀 더 효율적이라고 생각하는 조건문을 선택해서 작성하면 된다.

그리고 중첩 횟수에는 제한이 없으며

중첩 조건으로 구현할수록 더욱 세밀한 조건을 구현할 수 있다.

그리고 중첩 조건문에서는 변수가 어디에 선언되어 있는가에 따라서

사용할 수 있는 구역이 있고 사용할 수 없는 구역이 존재한다.

일반적으로 프로그래밍에서는 { }(중괄호)를 기준으로 구역을 나누는데

{ }안에서 선언된 변수는 해당 { }안에서만 사용이 가능하고

해당 { }밖에서는 사용이 불가능하다.

그리고 { }안에 속하지 않은 별개의 구역이라면 같은 변수명으로도 선언이 가능하지만

{ }안이라면 같은 변수명으로 선언하는 것은 불가능하다.

Comments