2011년 4월 29일 금요일

자바의 배열(Array)

자바에서 배열(Array)이란 리스트 혹은 집합 같은 개념으로 같은 종류끼리 모아놓은 것이라고 생각하면 될 것이다. 여러분이 재미있는 게임이나 사진 혹은 음악 자료들을 다운받아서 게임이나 음악은 장르별로 사진은 장소나 시간으로 디렉토리를 분류해서 보기 쉽도록 모아놓지 않는가? 프로그래밍에서도 배열을 사용하는 이유는 똑같이 자료들을 효율적으로 관리해서 보다 빠르게 찾기 위함이다.

배열([ ])은 int,double,char,boolean타입등의 자료형 배열과 클래스 같은 String타입등의 객체형 배열로 나뉘어지고 이밖에도 1차원 배열, 2차원 배열, 3차원 배열등 배열의 배열을 원하는데로 만들수 있는 길이 열려있다. 즉, 배열을 만든 상태(1차원)에서 요소별로 또 배열(2차원)을 만들고 다시 거기서 배열(3차원)을 만들고 이런식으로 계속해서 배열을 만드는 것이 가능하다. 자바에서는 이를 다차원 배열이라고 부른다.

그럼 여기서 배열은 어떻게 사용하는지를 본격적으로 알아보자. 배열은 자신이 어떤 타입인지 일단 선언 즉 초기화시켜 주어야 하고 그 다음에 배열을 만들기 위한 메모리 공간을 new 라는 키워드를 통해 생성해서 얼마만큼의 공간을 확보할지 알려주어야 한다. 그리고 생성된 배열에 넣기위한 요소들을 추가해 가는 것이 자바에서 배열을 만드는 요체라 할수 있겠다.

객체 생성을 할때 new 라는 키워드를 사용한다고 예전에 잠시 배운바 있다. 거기서 우리가 추리할수 있는바는? 그렇다.^^ 배열도 객체이기 때문에 new 를 사용할수 있는 것이다. 객체에 대한 내용은 다음에 클래스와 메소드에 관한 내용을 다룰때 자세히 설명할 것이니 너무 걱정하지 말고 지금은 배열에만 집중하기 바란다. 그럼 배열을 공식으로 한번 써보면 이와 같다.

배열종류[ ] 배열이름=new 배열종류[배열길이];

일단 정수 int 타입을 통해 알기쉽게 정리해 보겠다.


int[ ] a;
int a[ ];

배열을 어떤 타입으로 할것인지 초기화(선언)시키고 있는데 위의 두가지 방식으로 표현할수 있다. 당연한거지만 중간에 띄워쓰기 같은 것은 자바에서 인식하지 않으니 항상 염려하지 말기 바라며 이제 이 부분은 앞으로도 더이상 언급하지 않겠다.ㅎㅎ 자바에서 어디서나 가장 많이 쓰이는 방식은 첫번째 방식이고 이를 사용하는 것을 추천한다. 아무래도 두번째보다는 첫번째 표현이 배열이라는 것을 자료타입을 보자마자 바로 판단이 가능해서 보편적으로 쓰인다.

a=new int[3];

다음 단계는 배열을 new를 통해 생성시키는 단계이다. 또한 공간은 3을 주어 3가지 요소를 넣을 준비를 하게 만드는 과정이다. 이 과정을 다른 변수 초기화처럼 배열도 아래와 같이 한줄로 쓸수 있다.

int[ ] a=new int[3];

이제 정수타입을 저장할수 있는 공간 세군데를 확보하였으니 관련 자료형에 대한 값을 넣어주면 배열이 완성된다. 아직은 관련값을 넣어주지 않은 상태인데 자바에서 관련값을 넣기 이전인 지금, 이제 막 완성된 배열의 요소들(a[0],a[1],a[2])은 자동적으로 0이 세팅된다. 그런 까닭에 일반 변수들은 초기화시키지 않고 즉 관련값을 넣지 않고 출력시키면 에러가 나지만 배열은 초기화(initialize)시키지 않고 배열 요소들을 출력해도 에러없이 자동세팅된 0을 출력한다. 믿어지지 않으면 직접 실험해보기 바란다.^^

이제 관련값을 배열에 넣어보겠다

a[0]=1;
a[1]=2;
a[2]=3;

index 즉 공간의 지점은 항상 0부터 시작한다. 본 강이의 자바 강좌를 빠지지 않고 열공한 이들이라면 그 이유(?)에 대해서 이미 인지하고 있을 것이다. 위처럼 긴 과정(?)을 거칠 필요없이 아래처럼 짧게 선언할수도 있다.

int[ ] a=new int[ ]{1,2,3};
int[ ] a={1,2,3};

자바에서 배열을 초기화시키는 방법인데 위의 두가지 중 아무거나 사용가능하나 첫번째 방식이 더 명확하므로 이를 추천한다. 표현방식만 다를뿐이지 자바에서 인식해서 읽어드리는 과정은 똑같다. 

지금은 배열의 길이가 길지않아 관련값을 출력하는게 힘들지 않지만 값이 10개나 20개 혹은 그 이상이라면 어느 세월에 배열 요소들을 다 출력할수 있을까? ㅎㅎ 인덱스와 관련값이 일정한 크기로 증가하고 있다. 증감연산자가 떠오르지 않는가? 이럴때 써먹으라고 우리가 저번에 열심히 반복문에 대해서 배운 것이다. 뛰어난 프로그래머는 정신적으로는 부지런해야하지만 몸은 게을러야한다.ㅎㅎ 어떤 의미인지는 여러분이 알것이라 믿고 조금더 설명하겠다.

배열이름.length

배열의 길이를 알수 있는 명령어다. 배열의 길이를 알아야 반복문을 쓰더라도 언제 중지할지 그 기준을 만들수가 있다. for문의 조건문을 떠올리면 왜 필요한지 이해하리라 본다. 위의 예제에서는 길이를 알려면 배열명인 a를 이용해 아래와 같이 쓰면 될것이다.

a.length

위의 length는 배열을 완성하면 언제든지 배열의 길이를 알수 있도록 자바에서 만들어놓은 명령어이다. 밑의 그림은 인덱스([?])가 0부터 9까지인 길이 10의 배열인데 9번째 값은 배열공간 [8]에 들어간다는 것을 말한다. 배열의 지점인 인덱스는 항상 0부터 시작하니까 말이다. 이 부분 때문에 많은 이들이 자바의 배열을 어려워하는 것이나 알고보면 별것 아니다.^;


자 그럼 흥미로운 아래 예제(?)를 통해서 배열을 어떻게 만들고 배열의 길이는 어떻게 써먹는지 보기로 하자. 예제의 내용은 이러하다. 아이돌 가수로 유명한 아이유가 방송사에 나가기전 점검을 위해 소속사에서 3가지 테스트를 보았다. 물론 아이유를 비롯 소속사에 속해 있는 모든 가수들이 이 테스트를 치뤘다. 보컬, 율동, 의상에 한해 분류별로 점수를 매겼는데 아이유의 경우 보컬은 98점, 율동은 91점, 의상은 83점이 나왔다. 다른 가수들과의 빠른 비교를 위해 총점과 평균점수가 필요한데 이것을 해결하기 위한게 우리의 사명(?)이다.


가수 아이유의 테스트 결과

Total=272점
Average=90.0점

수고하셨습니다.
테스트를 우수한 성적으로 통과하였습니다.

위의 예제를 컴파일하고 실행하면 위와 같은 결과가 나올 것이다. 프로그램이 조금 긴듯하지만 자바의 제어문을 이미 공부한 여러분들은 배열 이외에는 별 어려운 사항은 없을 것이다. 그럼 프로그램을 분석해 보자. 처음에 배열 공간 3개를 초기화하고 생성하는 과정이다. 총점(sum)과 avg(평균)은 int과 double타입으로 선언하였다. 생성된 배열공간에 획득한 점수를 차례대로 입력하였다. for문을 통해 총점을 계산하고 iu.length를 통해 평균을 계산하였다. iu.length가 얼마(3)인지는 당연히 알것이지만 몰라도 된다. 이것은 자바에서 배열을 만들면 자동으로 계산하기 때문이다. 여기서 / 표시는 나누라는 뜻이고 컴퓨터에서 연산기호는 덧셈+, 뺄셈-, 곱하기*, 나누기/, 나머지% 로 표시한다. 다음에 결과를 출력하는데 if문을 통해 90점 이상이면 통과 메세지를 그 미만이면 else구문을 통해 재도전 메세지를 추가적으로 표시하도록 만들었는데 테스트에서 아이유는 90점을 받아 가까스로 위기를 모면하고 있는 프로그램이다.ㅎㅎ

예제를 보면서 한가지 아쉬움이 남을 것이다. 우리가 공부하는 입장이므로 시간 절약하기 위해서 저렇게 미리 테스트값을 넣고 프로그램을 돌리지만 현실에서는 테스트 할때마다 매번 다시 코드를 수정해야하는 것에 번거로움을 느낄 것이다. 필자는 이런 상황을 미리 예견(!)하고 유저한테서 입력값을 받을수 있는 방법을 여러 각도로 조명한바 있다. 키보드로 입력값(테스트 점수)을 받아서 테스트 결과를 출력하는 예제를 여러분의 힘으로 한번 만들어 보기 바란다. 배열을 이용한 한편의 작품이 될것이다. 작품 이름은 "아이유 컨디션 테스트" ^^ 항상 그렇지만 프로그램을 본인이 만든것과 비교하기를 희망하는 이들을 위해 본 프로그램을 아래에 올린다. 시도도 해보지 않고 바로 답만 보는 악의 무리들(?)이 없기를 바라고 코드가 이해되지 않는다면 입출력에 관련된 강이의 예전 자바강좌를 보면 다시 기억이 날것이니 설명은 생략하겠다.


이번엔 객체형 배열을 설명할텐데 어떻게 쓰는지 사용방법을 기술해 보겠다.

String[ ] s;
s=new String[3];

String[ ] s=new String[3]

따로 쓰던 같이 쓰던 상관없다. 선언하고 생성하는 과정은 같다. 여기서 여러분은 이런 궁금증이 생길 것이다. 자바의 객체형 배열에서는 관련값을 넣기 이전에 무엇으로 세팅이 될까? 일반 자료형 배열인 숫자같은 정수형 타입이 아니니 0 대신에 null 이 자동으로 세팅되도록 만들어져 있다. null은 객체가 참조하는 곳이 없을때 즉 자기 자신만 홀로서기(?)하고 있을때 null이라는 표현을 쓴다.(객체에 관해서는 후에 더 자세히 거론하겠다.)

자바에서는 왜 배열 요소들을 자동으로 세팅하게 만들었을까? 배열 요소가 한두개가 아니라 수십개라고 생각해 보라. 그런데 관련값은 현재 수십개중에 몇개밖에 넣을게 없는 상황이라면 어떻게 하겠는가? 만약 배열이 자동으로 초기화되지 않는다면 배열 요소들의 일부만 쓰더라도 프로그램을 정상적으로 컴파일하고 작동시킬려면 남아있는 배열 요소들에 0이나 null값을 일일이 넣어주는 수고(?)를 해야할 것이다. 이런 수고를 덜어준 자바(?)에게 우리는 경의를 표해야 할 것이다. 일동 경례~ ㅎㅎ

자료형에 객체형 타입이 들어갔을뿐 배열을 생성하는 과정은 보다시피 다를게 없다. 허나 관련값을 넣어주는 방식이 다르니 아래를 주의깊게 보기 바란다.

s[0]=new String("아이유");
s[1]=new String("카라");
s[2]=new String("소녀시대");

String[ ] s={new String("아이유"), new String("카라"), new String("소녀시대")};

String[ ] s=new String[ ]{new String("아이유"), new String("카라"), new String("소녀시대")};

세가지 중 아무거나 써도 되지만 첫번째나 세번째 방식이 클리어하므로 될수 있으면 이중에서 쓰도록 하자. 특히 괄호와 따옴표를 틀리지 않도록 주의해서 쓰기 바란다. 객체형 배열은 어떤 식으로 사용해야 되는지 이제 감이 올것이다. 위의 세가지 방식 모두 예제를 통해 잘되는지 직접 실행해 보기 바란다.


세가지 방식을 각각 group, title, member라는 배열명을 통해 제대로 작동되는지 프로그램을 만들어 본것이다. 게으름 피우지 말고 직접 코드 쳐가면서 걸그룹과 만나는 시간(?)을 가져보기 바란다. 실행을 하면 결과값은 아래와 같을 것이다.

가수이름: 아이유
노래제목: 좋은 날
멤버수: 한명

가수이름: 카라
노래제목: 루팡
멤버수: 다섯명

가수이름: 소녀시대
노래제목: 훗
멤버수: 아홉명

오늘은 배열이 어떤 상황에서 유용하게 쓰이는지를 몸소 체험(?)했을줄 믿는다. 다음 시간에는 배열 중에서도 2차원이나 그 이상의 다차원 배열에 대해서 공부해 보도록 하겠다. 이번 시간에 배운 배열을 확실하게 정립하면 다차원 배열을 공부하는데 훨씬 수월할 것이다. 그럼 다음 시간을 기약하면서 오늘 강좌는 여기서 마치겠다.^^

2011년 4월 27일 수요일

자바의 제어문(try)


우리가 프로그램을 만들다 보면 오류가 생길때가 있다. 이럴 경우 우리가 잡을수 있는 오류랑 우리가 잡을수 없는 오류로 나누어지는데 우리가 고칠수 있는 대부분의 오류를 Exception이라고 하고 우리가 잡기 힘든 오류를 말그대로 Error라 한다. Error는 메모리 문제라든가 치명적인 에러라 쉽게 고칠수 있는 부분이 아니지만 Exception에 관계된 오류는 우리가 프로그램으로 커버가 가능하다. 우리는 우리가 할수있는것(?)만 잡아보기로 하자.

자바의 예외처리 구문을 상당히 어려워하는 이가 많다. 평상시 코드의 수정으로 인해 대부분 극복이 되니 지나칠수도 있고 일단 용어(?) 자체가 굉장히 생소하고 영어가 무진장 길다.ㅎㅎ 그래서 특히나 어려워하는지도......아닌감?? 그러나 두려워하지 말자. 오늘 차근차근 공부하다보면 어느새 여러분은 이런 오류가 나도 덤덤해질테니까 말이다.^^

Exception은 try catch 구문으로 잡을수 있는 비교적 작은 에러를 말하는 것으로 우리는 제어문에서 이를 예외처리(Exception Control)라 부른다. 보통 프로그램을 짜다가 자주 접하는 예외는 RuntimeException이라고 부르는 오류인데 아마 예제를 실행하다가 한번쯤 접해봤을지도 모르겠다. 컴파일은 되는데 작동이 안되는 경우다. 이런건 대부분 코딩을 잘못해서 생기는 문제이니 이런 예외가 발생하면 프로그램에서 잘못된 코드는 없는지 살펴보기 바란다. 대부분의 오류가 코딩시 잘못되어 발생하는 문제이지만 상황에 따라서 try catch 구문을 사용해야만 하는 경우가 생기는데 자바에서 이런 예외를 어떻게 다룰수 있는지 집중적으로 알아보도록 하겠다.

try
{
//예외가 발생하는 부분을 try 블록으로 감싸준다.
}

catch (?Exception e) //괄호안에는 exception 예외 종류를 써준다.
{
명령문1; //예외가 발생했을때 실행할 부분을 적어준다.
...
}

catch (??Exception e) //예외를 하나만 잡을수 있는건 아니다.
{
명령문2; //예외가 발생했을때 명령처리할 부분이다.
...
}

catch (???Exception e)
{
명령문3; //예외 발생시 명령 처리한다.
...
}

..
...
....//catch 구문은 여러개가 가능하다.

finally
{
명령문5;
...
}

finally 구문은 try catch 다음의 맨 아래에 위치하며 예외가 일어나든 말든 무조건 실행된다. catch나 finally 구문은 없어도 된다. 허나 둘중 하나는 반드시 있어야 한다. 단지 꼭 실행해야할 명령이 있을때 사용하면 된다. 조금더 자세히 설명하자면 try 블록에서 예외가 일어난다. 당연히 그래서 try 블록을 그곳에 감싸놓게 될것이다. catch는 바로 이 try 블록에서 어떤 exception 오류가 나는거에 따라 결정된다. 즉 첫번째 catch 구문에 적어놓은 ?Exception이 발생할경우 명령문2를 실행하고 finally 블록의 명령문5를 실행한다.(finally 구문은 무조건 실행된다.) 만약 try 블록에서 세번째 catch 구문에 적어놓은 ???Exception이 발생했다면 명령문3를 실행하고 finally 블록의 명령문5를 실행한다. 다 이해했겠지만 예제를 통해서 다시 한번 알아보자.


위의 예제는 배열을 이용한 것이다. 변수 a에는 하나의 숫자만 들어가지만 배열을 이용하면 여러개의 요소들을 집어넣고 필요할때 빼서 쓸수가 있다. 예전 입출력 예제에서 잠시 언급한 적이 있을텐데 프로그램을 설명하자면 a[0]이라는 공간에 1이 들어가고 a[1]에는 2가 a[2]에는 3이라는 숫자가 들어가는 배열이다. [ ]안을 a라는 공간의 한 지점(index)이라고 생각하면 이해가 쉬울것이다. 창고 a가 있는데 0번방에는 숫자 1을 1번방에는 숫자 2를... 뭐 이런식으로 생각하면 된다.

int[ ] a=new int[3];
a[0]=1;
a[1]=2;
a[2]=3;

int[ ] a={1,2,3}; 이라는 명령은 a[0]=1, a[1]=2, a[2]=3 으로 만들라는 것과 같으며 위의 코드들의 줄임말이다. 문제는 a[3]이라는 공간은 없는데 거기다가 숫자 0을 집어넣으라고 하니 오류가 난다. 실행해보면 컴파일은 되고 작동은 하지 않으며 이런 메세지가 뜬다.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Test27.main(Test27.java:7)

메인메소드의 7번째줄에서 java.lang 패키지의 Exception 클래스에 관련된ArrayIndexOutOfBoundsException 오류(철자 되게 길구먼 -_*)가 나는걸 볼수 있다. 코딩상의 문제이므로 간단하게 이 코드 빼버리면 되지만 우리는 예외처리 공부를 해야하니까 try catch 블록을 이용해 이런 오류를 극복(?)시키는 방법을 알아보겠다. 기대하시라~ 쨔쨘...ㅎㅎ



위의 예제를 실행하면 아래와 같은 결과를 얻게 된다.

java.lang.ArrayIndexOutOfBoundsException: 3
6

오류가 나는 부분을 try 블록을 감싸고 아까 위에서 나온 오류를 catch문을 통해 받아서 관련 예외이름을 출력하라고 명령을 주었다. 6이라는 숫자를 보니 프로그램이 제대로 작동했다는 것을 알수 있다. 우리는 배열요소들을 전부 합하라는 명령을 내렸으니 1+2+3은 6이 된다. 이제 try catch 블록을 이용해 예외처리를 하는 방법에 대해서 어느 정도 이해했으리라 본다.

이제와서 하는 얘기지만 사실 catch문에 수식을 저렇게 명확하게 오류명을 적을 필요가 없다. 저 긴 영어를 언제 다 치냐? ㅎㅎ 이런 오류들은 Exception 클래스를 계승(?)받은 것이다. 따라서 맨 위의 대장 클래스인 Exception만 그냥 써줘도 어떤 예외든지 처리된다.^^ catch (Exception e) 이런 식으로만 써도 된다. 한번 실행해 보기 바란다. 되는지 안되는지... ㅎㅎ 늦게 알려줘서 필자를 탓하는 이가 있을지 모르겠지만 우리는 공부하는 입장에서 정석을 제대로 알아야 하지 않겠는가? *.^

또한 메소드내에서 오류가 날 경우가 있는데 이럴때는 메소드도 예외처리하면 된다. 메소드 옆에 throws 키워드를 이용해 예외를 다른곳으로 보내서 처리하는 방법이 있다. 예전 입출력 시간에 필자가 언급한바 있다. 그래도 다시 한번 간략히 설명하자면

결과값 ??ex( ) throws ???Exception
{
//예외가 발생하는 부분
}

위와 같이 throws를 이용해 예외처리를 하면 이 메소드 ??ex( )를 쓰기 위해 다른 곳에서 실행하는 곳이 있을 것이다. 어디선가 이렇게 아래와 같이 메소드를 실행하는 곳이 있을텐데 바로 그곳을 try 블록으로 감싸고 catch 블록을 써서 예외처리를 아까처럼 하면 된다.

try
{
??ex( );
}
catch (???Exception e)
{
...
}

기본에 충실하면 이런 정도의 응용은 어렵지 않을 것이다. 이 밖에 Exception 클래스를 본인이 직접 상속받고 클래스 생성자에 따로 예외오류를 규정하고 사용하는 방법도 있다. 이런 방식은 오류가 나는 부분 메소드에 아까와 같이 throws로 오류 부분을 쓰고 다른 곳이 아닌 바로 그 메소드 안의 명령문에서 throw new라는 키워드를 써주고 임의로 만든 오류 클래스를 객체 생성하면 예외처리가 된다. 아직 클래스 상속이라는 것을 배우지 않았으므로 그런게 있다라고만 알아두고 나중에 개념을 확립한후에 컴백해서 다시 읽어보면 모든게 이해가 될 것이니 아까했던 try catch 구문이나 확실하게 알아두도록 하자. 뒤에 언급한 throws 예외처리 부분은 try catch 구문에 비하면 이미 저번에 한번 해봤기도 하고 비교적 쉬운 편이므로 그리 염려할 필요(?)가 없을 것이다.^^

자바의 제어문(while)

while loop이라고 불리는 반복문 while에 대해서 알아보자. 자바의 반복문을 공부하다 보면 for를 써야될지 while을 써야될지 고민(?)에 잠기는 이가 많다. 오늘 강좌를 열심히 파다보면 그 의문(?)이 풀릴지도 모른다는 기대를 하면서 평소처럼 계속 전진해 보기 바란다.^^ 자바에서 while은 코드상으로 아래와 같이 표현된다.

while (조건문)
{
명령문1;
명령문2;
...
......
}

while문은 조건문이 true인 동안에는 { } 안의 명령들이 실행되면서 for문처럼 반복된다. for문의 경우 초기식과 증감식을 수식(괄호안)에 써주어야 하나 while은 수식에 참인지 거짓인지를 판단하는 조건문만 써주면 되고 증감식을 { } 내부에 쓸수가 있어 좀더 다양한 표현이 가능하다고 할수 있겠다. 반복문을 실행할때 단순히 해당 명령문을 n번 실행하는 것으로 해결이 안되는 복잡한 경우가 있는데 그럴 경우 for 대신에 while을 쓴다. 그러나 확실한 범위를 알고 초기식과 증감식이 명확할 경우 for문을 쓰면 된다. while과 for는 하는 일이 같으나 위와 같은 차이점들이 있다. 프로그램을 짤때 for문으로 시도를 해보고 그래도 문제가 있으면 while문으로 고쳐서 문제해결을 시도하면 될 것이다. 예제를 통해 while문에 대해서 좀더 알아보기로 하자.


그냥 예제만 봐도 이해가 될것이다. for문의 for (int i=0; i<=2; i++) 과 똑같은 식이 된다. 처음에 0을 넣어 비교해서 참이면 안의 명령들을 실행하고 while문으로 돌아와 1을 넣고...3을 넣을때는 거짓이므로 while문을 빠져나오며 프로그램이 종료된다. 따라서 결과값은 0 1 2 가 될 것이다. for문을 벌써 습득(?)한 여러분에겐 문제될게 없으리라 본다.^^

while도 다중 for문처럼 여러개의 while을 쓰는 것이 가능하다. 여기서는 두개만 써서 가능하다는 것만 보여주겠다.


코드를 입력하고 결과를 예상해보고 준비되었으면 실행해 보도록 한다.

0
1
2
i의 값은 0입니다.
0
1
2
i의 값은 1입니다.
0
1
2
i의 값은 2입니다.

간단히 요약하면 i가 한번 돌아갈때 j는 세번씩 돌아가는 프로그램이다. 이번에는 while보다는 쓰는 빈도가 약하지만 유용하게 쓰일수 있는 do while 구문에 대해서 알아보기로 하겠다.

do
{
명령문1;
명령문2;
...
...
}
while (조건문); //끝에 세미콜론을 붙인다는 것을 잊지말자!


공식은 위와 같으며 while문과 다른점은 조건문을 묻기전 do { } 안에 있는 명령문들을 참과 거짓에 관계없이 즉 조건문이 false가 되더라도 일단 한번 실행한다는 것이다. 그리고 조건문을 비교하고 참이면 do { } 안에 있는 명령문들을 기본 while문처럼 계속 반복하고 조건문이 거짓이 될때 do while문을 빠져나오며 프로그램이 종료된다. 아래의 예제를 보면 이해가 쉬울 것이다.


do while 조건문을 보기에 앞서 프로그램 코드 순서대로 진행하면 큰 무리가 없을 것이다. 처음에 i 값이 0으로 주어져서 0을 출력하고 i에 1을 더했다. 그리고 조건문에서 i가 1보다 작거나 같은지를 묻는다. 지금 i값은 1이므로 true가 성립하고 다시 do 블록안으로 들어가서 i값인 1을 출력한다. 그 다음 1을 증가시키고 i값이 2가 된 상태에서 조건문을 만난다. 이번에는 조건문이 거짓이므로 do while문을 빠져나오고 프로그램은 끝난다. 아~ 심플하다. ^^ 따라서 결과는 이렇게 될것이다.

i의 값은 0입니다.
i의 값은 1입니다.

for문에 비해서 수식이 간단하므로 오히려 while문이 쉽게 느껴질 것이다. 진도를 더 나갈까 하다가 여러분의 피곤이 심히 누적(?)된듯하여 오늘은 그만하겠다. 자바의 제어문 중에서 반복문 역시 쓰이는 비중이 아주 높다. 반복문을 쓰지 않아도 프로그램은 가능할 것이다. 그러나 같은 코드를 5번 10번 쓸것이냐 아니면 반복문 하나를 짜서 다 커버할 것이냐고 묻는다면 바보(?)가 아닌 이상 for문이나 while문은 반드시 어떻게 사용하는지 알아야한다. 빨리 끝낸만큼 남는시간을 더 알차게 쓰기 바란다. 이상~ ㅎㅎ

2011년 4월 26일 화요일

자바의 제어문(for)

자바의 제어문 중에서도 가장 많이 쓰이는 것 중에 하나가 반복문이다. 자바에서 반복을 행하는 for문은 소스를 볼때마다 없으면 이상할 정도로 자주 보게 될것인데 당연하지만 같은 내용을 두번 세번 만들 필요없이 한번만 고생(?)하면 되니 이보다 더 좋을수는 없을 것이다.^^


for loop..for looping... 포루프.... 포루핑(루팡이 아님 --*), 오늘은 반복적인 일을 수행하게 만드는 for문을 공부해 보자. 공식은 아래와 같다.

for (initialization; termination; increment)
{
   statement
}

잘 모르겠으면 아래를 보자.^^

for (초기문; 조건문; 증감문)
{
명령문1;
명령문2;
명령문3;
...
....
.....
}

예제를 보면 이해가 쉬울 것이다. for문에서 세미콜론(;)은 분류를 위해 중간에 두개만 들어간다. for 반복문은 우리가 저번에 배웠던 증감연산자와 뗄래야 뗄수 없는 관계이다. 반복을 시킬수 있는 원동력이 바로 증감연산자이기 때문이다. 그럼 뜸(?) 그만 들일테니 이제 예제를 보자.^^


1부터 3까지 출력하는 예제인데 어떤식으로 반복이 되는지 설명하겠다. for문의 작동원리는 초기값 즉 시작하는 값이 초기문에 있고 그 값을 두번째에 위치한 조건문에 대입해서 조건이 참이면 아래 명령들을 처리하고 거짓이면 for문을 빠져나온다. for문에서 참일때 처리해야하는 명령들은 { } 안에 위치한다. 다시 돌아와서 조건이 참이 나와 명령들을 처리하고 나면 증감문을 실행한다. 증감문이 실행되고 난 후에는 다시 for문으로 돌아와 증감문의 연산대로, 예제의 경우 i값에 1을 더한값이 다시 조건문에 대입되고 위와 같은 과정들을 계속 반복하며 조건문에서 거짓이 나올때까지 for문은 계속 반복된다. 조건문을 만들때는 프로그램의 목적에 따라 반복을 중단해야되는 시점 즉 거짓이 나오는 시점을 반드시 만들어야 한다. 그렇지 않으면 컴퓨터 망가질때까지 for문이 반복(?)될테니까 말이다.ㅎㅎ

본 예제는 i에 0이 들어가면서 for 루프가 시작된다. 그런데 안에 if문이 있는데 0이 아닐때만 i를 출력하라고 한다. 처음의 i값이 0이므로 출력을 하지 않고 다시 for문으로 돌아가 i에 1이 들어가면서 for 룹이 반복된다. 1도 3보다 작거나 같으므로 명령이 처리되며 1은 0이랑 같지 않으므로 이번에는 안에 있는 명령이 실행되면서 1이라는 숫자가 화면에 출력된다. 2도 마찬가지고 3도 마찬가지인데 i에 4가 들어갔을때는 조건문이 거짓이 되므로 for문을 빠져나오며 프로그램이 종료된다. for문에서 초기문의 값은 말 그대로 처음 시작될때 한번만 써먹고 다음엔 써먹을 일이 없다.


위의 예제는 for문에서 초기문과 증감문을 바깥으로 빼고 조건문만 남겨둔 예제이다. 이렇게 초기문이나 증감문을 for문에서 빼내는게 가능하다. 허나 조건문은 꼭 있어야되며 앞과 뒤에 ; 세미콜론은 반드시 있어야 된다. for문의 기본구성을 깨뜨려서는 안되니까 말이다. ^^


위의 두 예제를 보면 하나는 if문에 하나는 for문에 break 명령이 들어가 있다. switch문에서 break 용도에 대해 이미 알아보았는데 이 명령은 switch에서만 쓸수 있는게 아니다. 다른 제어문에서도 쓸수 있다는걸 알려주기 위해 위의 예제를 만들어보았다. 어떤 답이 출력될지 둘다 생각해보고 프로그램을 실행해 보기로 하자. 다 해본걸로 믿고 계속 진행하겠다.

첫번째는 if문에서 break가 걸려있는데 처음의 i값이 0일때는 아예 if문을 들어가지 못하니 break를 만나지 않는다. 반복해서 다시 if문을 만날때는 i값이 1이므로 들어가서 1을 화면에 출력하고 break를 만나므로 그 다음부터는 if문을 실행하지 않는다. 두번째는 처음부터 break를 만나는데 for문에 위치하므로 for문을 더이상 실행하지 않는다. 따라서 for문 이전에 출력을 지시했던 프린트 명령 이외에는 i값을 아무것도 프린트하지 못하고 프로그램이 종료된다. break는 불가피하게 일정 부분에서 알고리즘이 원활하게 수행되지 못할때 임시로 사용하는 개념이 강하다. 여러분이 프로그램을 만들때 예외가 없는 완벽한 알고리즘을 만든다면 break라는 명령은 그리 쓸일이 많지 않을 것이다.

그럼 이번엔 색다른 continue란 키워드에 대해서 공부해 보겠다.


예제를 보면 if문 안에 continue란 명령이 들어가 있다. 이건 무엇을 뜻하는 것인가? continue란 명령을 만날 경우 가장 가까이 있는 for문의 닫는 } 중괄호로 이동한다고 생각하면 된다. 즉 for문에서 증감문이 실행되기 전까지 안에서 행해야될 명령들을 뛰어넘는 것이다. 결과를 보면 아래와 같이 나온다.

0번 루프
0
0체크
1번 루프
2번 루프
3번 루프

처음에는 0이라 continue를 만나지 않으므로 숫자 "0"과 "0체크"라는 표현을 프린트한다. 그러나 두번째부터는 continue를 만나므로 계속해서 for문의 }로 이동을 하므로 다른 명령문들을 처리하지 않는다. continue란 키워드는 잘 쓰이지 않는 편이라 자바를 많이 한 이들도 생소할 것이라 생각된다. 허나 알아두면 써먹을데가 한두번쯤은 나올테니 속는셈치고 공부해보자.^^


위의 예제를 보면 알겠지만 for문은 여러개 쓰는게 가능하다. 우리는 이것을 다중 for문이라 하는데 이런 for loop이 자바에서는 상당히 많이 쓰이므로 어떻게 반복되는지 이번 기회에 확실하게 숙지하기 바란다. C 루프를 보면 continue가 들어있다. 아까 말했던데로 continue를 만나면 가장 가까운 for 루프의 } 닫는 중괄호로 이동해서 증감연산문을 실행하고 다시 그 for 루프의 조건문으로 이동해 값을 비교하면서 프로그램이 계속 진행된다. 여기서는 가장 가까운 for문이 C 루프가 될것이다. 필자가 이번 예제에 온 열정과 정열을 쏟아부었으니 프로그램만 돌려봐도 이해가 절로 될것이다. ^^ 제발~ ㅎㅎ 그럼 결과값은 아래와 같다. 다중 for 루프이므로 무지 길다. --;

========0번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=0, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=0, b=0, c=1
All numbers are printed.
========2번 C 루프========
========1번 B 루프========
========0번 C 루프========
a=0, b=1, c=0
All numbers are printed.
========1번 C 루프========
a=0, b=1, c=1
All numbers are printed.
========2번 C 루프========
========2번 B 루프========
========0번 C 루프========
a=0, b=2, c=0
All numbers are printed.
========1번 C 루프========
a=0, b=2, c=1
All numbers are printed.
========2번 C 루프========
========3번 B 루프========
========0번 C 루프========
a=0, b=3, c=0
All numbers are printed.
========1번 C 루프========
a=0, b=3, c=1
All numbers are printed.
========2번 C 루프========
========1번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=1, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=1, b=0, c=1
All numbers are printed.
========2번 C 루프========
========1번 B 루프========
========0번 C 루프========
a=1, b=1, c=0
All numbers are printed.
========1번 C 루프========
a=1, b=1, c=1
All numbers are printed.
========2번 C 루프========
========2번 B 루프========
========0번 C 루프========
a=1, b=2, c=0
All numbers are printed.
========1번 C 루프========
a=1, b=2, c=1
All numbers are printed.
========2번 C 루프========
========3번 B 루프========
========0번 C 루프========
a=1, b=3, c=0
All numbers are printed.
========1번 C 루프========
a=1, b=3, c=1
All numbers are printed.
========2번 C 루프========
========2번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=2, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=2, b=0, c=1
All numbers are printed.
========2번 C 루프========
========1번 B 루프========
========0번 C 루프========
a=2, b=1, c=0
All numbers are printed.
========1번 C 루프========
a=2, b=1, c=1
All numbers are printed.
========2번 C 루프========
========2번 B 루프========
========0번 C 루프========
a=2, b=2, c=0
All numbers are printed.
========1번 C 루프========
a=2, b=2, c=1
All numbers are printed.
========2번 C 루프========
========3번 B 루프========
========0번 C 루프========
a=2, b=3, c=0
All numbers are printed.
========1번 C 루프========
a=2, b=3, c=1
All numbers are printed.
========2번 C 루프========
========3번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=3, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=3, b=0, c=1
All numbers are printed.
========2번 C 루프========
========1번 B 루프========
========0번 C 루프========
a=3, b=1, c=0
All numbers are printed.
========1번 C 루프========
a=3, b=1, c=1
All numbers are printed.
========2번 C 루프========
========2번 B 루프========
========0번 C 루프========
a=3, b=2, c=0
All numbers are printed.
========1번 C 루프========
a=3, b=2, c=1
All numbers are printed.
========2번 C 루프========
========3번 B 루프========
========0번 C 루프========
a=3, b=3, c=0
All numbers are printed.
========1번 C 루프========
a=3, b=3, c=1
All numbers are printed.
========2번 C 루프========

마지막으로 본 예제에서는 continue를 만났을때 가장 가까운 for문인 C 루프로 이동을 했다. 그러면 그냥 원하는 for문으로 이동할수는 없을까? 물론 있다. continue outer; 라는 명령을 쓰고 이동하고 싶은 for문 앞에 outer: 라고 써주면 그쪽으로 이동한다. 예제를 보고 결과를 비교해보면 어떤 차이가 있는지 알게 될것이다.


========0번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=0, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=0, b=0, c=1
All numbers are printed.
========2번 C 루프========
========1번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=1, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=1, b=0, c=1
All numbers are printed.
========2번 C 루프========
========2번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=2, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=2, b=0, c=1
All numbers are printed.
========2번 C 루프========
========3번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=3, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=3, b=0, c=1
All numbers are printed.
========2번 C 루프========

곁다리로 조금더 공부해 보자면 아래와 같은 for 루프도 있다.

for ( ; ; )
{
..
...
}

이런 식으로 쓰면 infinite loop이라고 하여 무한루프 즉 중지하지 않고 끝없이 반복된다. 그리고 enhanced for 구문이라고 컬렉션과 배열일때 기존의 for 구문에 비해서 유용하게 써먹을수 있는 향상(?)된 기법으로 for loop을 아래와 같이 간단하게 표현할수도 있다.

for (카운트 변수 : 관련 배열)
//중간에 쓴것은 세미콜론이 아니라 그냥 콜론(:)이다.

앞으로는 이런 방식이 대세(?)를 이루게 될것인데 이제 쓰는 방법을 알았으니 아래 예제를 보면서 여러분도 이런 업그레이드된 방법을 쓰는데 익숙해지기 바란다.^^


숫자: 1
숫자: 2
숫자: 3
숫자: 4
숫자: 5


이로서 for문에 대해서 공부해 보았다. 자바에서 for문은 건드리면 툭하고 나올 정도로 많이 쓰이고 특히 다중 for문은 더 자주 쓰여 우리를 매우 피곤하게 할것이니 이번 기회에 개념을 확실하게 정리해놓기 바란다. 그리고 마지막에 본 기존 for문에 비해 보다 파워풀한 성능을 제공하는 enhanced for 구문은 보는 것처럼 내용이 명료하고 쓰기 편하여 여러 프로그램에서 자주 보게될 것이니 어떻게 쓰는지 꼭 기억하기 바란다.^^

자바의 제어문(switch)

오늘은 자바의 switch문에 대해서 알아보겠다.

switch (수식)
{
case 정수1: 명령문1;
case 정수2: 명령문2;
case 정수3: 명령문3;
......
......
case 정수8:case 정수9:명령문9;
//한 명령문에 케이스 여러개 만들수도 있다.
default: 명령n; //해당하는 케이스가 없어도 default(?) 모드니까 기본적으로 실행된다. 필요하지 않으면 안만들어도 된다.
}

수식과 정수가 일치하는 곳에서부터 밑으로 쭈욱 실행한다. 예제를 보면 이해가 한결 쉬울 것이다. 그럼 예제를 살펴보자.




위의 코드를 짜고 답이 어떻게 나올지 예상해 보자. 수식에 3이 들어가므로 case 3부터 default문까지 실행된다. 따라서 결과는 아래와 같다.

세엣
다섯
일곱


그럼 n에다가 10을 집어넣으면 어떻게 될까? 10과 매치되는 케이스는 없으므로 기본값인 "끝"이 출력된다. n대신에 n=n+1 같은 수식을 넣어서 계산도 가능하니 응용해 보기 바란다. 이번에는 해당케이스만 실행하고 switch문을 빠져나올수 있는 break에 대해서 알아보기로 하자.



위의 예제는 스위치문에 n과 m을 더한 숫자 7이 들어간다. 그래서 해당 케이스 7에 들어있는  명령문이 실행된다. 결과는 아래와 같다.

Total=7

해당 케이스부터 아래 default문까지 실행되어야 하는데 default문이 실행되지 않았다. break를 만나면 위와같이 switch문을 빠져나올수 있다. 그럼 이번에는 m값을 5로 고쳐보자. 그럼 스위치에 들어가는 값이 8이 된다. 그런데 케이스 8이 없다. 해당사항이 없으므로 기본모드인 default문이 작동된다. 그러면 결과는 아래와 같이 된다.

해당사항 없음
Total=0

이번에는 필자가 조금 헤깔릴만한 switch문을 만들어보았다. 과연 다 맞출수 있는 똘똘한 자바인(?)이 있을까? 그럼 아래의 예제를 보기 바란다.


switch문과 break, 그리고 증감연산자를 이용한 예제이다. 자바를 실행하기전 무엇이 나올지 메모지에 한번 써보기로 한다. 저번 시간에 배운 증감연산자의 내용을 기억한다면 맞출 확률이 상당히 높을 것이다. 그럼 결과를 살펴보자.

제로
하나
두울
세엣
1이라는 값이 x에 들어있음!

그럼 분석을 시작하겠다. x값으로 0을 주었다. switch문의 수식은 x++다. 이건 뭐라고 했징? x=x+1과 같다고 했다. 그래서 x=0+1 따라서 1이다. 그럼 case 1로 가야하는데 case 0에서부터 시작했다. 이상하다? ㅎㅎ 그런데 결과를 보니 x에 들어있는 값은 1이라고 제대로 나온다. 이제 감이 오는감? 그렇다. x++는 "선처리, 후연산"이라고 했다. 따라서, 값을 넘겨주는 처리부분을 먼저 행하니 x에 0이 대입되어 case 0으로 보내지고 x는 1을 증가시켜 연산하는 과정을 밟게 된다. 그리고 케이스 0부터 3까지 명령문들을 수행한다음 case 3에 break가 있으므로 switch문을 빠져나와 x값을 출력하고 있다.

if와 switch는 기능이 비슷하여 서로 상호작용이 가능하다. if로 써도되고 switch로 써도된다. 굳이 차이점을 말하라면 switch가 if에 비해 보기 편하다. 즉 아까 보다시피 가독성이 높다.ㅎㅎ 이렇게만 얘기하면 실망하겠지? 자 그럼 좀더 들어가보자면 switch는 char나 int 타입만 비교가능하지만 if는 String 타입도 가능하다. if는 순차적으로 원하는 조건을 살펴봐야 하지만 switch는 조건이 맞으면 해당란으로 바로 점프할수 있다. 또한 조건문이 많아지면 switch를 쓰는것이 더 빠르지만 요즘은 컴파일러 처리속도가 워낙 빠르니 그 효과를 기대하기가 어렵다. 굳이 따지자면 이런 차이들이 있겠지만 그냥 여러분 손가락이 안내(?)하는데로 가기 바란다. 저번과 이번 시간에 배운 조건문들은 수시로 쓰게 될테니 확실하게 이해하기 바라면서 오늘은 이만 마치겠다. ^^

자바의 제어문(if)

오늘부터는 자바의 제어문(Control Flow Statement)에 대해서 알아보기로 하겠다. 제어문이란 말 그대로 프로그램의 흐름을 제어하는 역활을 담당한다. 대표적인 제어문으로 조건을 나타내는 if나 switch, 반복을 나타내는 for나 while, 그리고 예외처리를 할수있는 try나 catch를 통해 프로그램을 여러분의 입맛대로 마음껏 요리할수 있게 될것이다.


이번 시간에는 조건을 나타내는 if문에 대해서 알아보기로 하겠다. 영어에서 풍기듯 만약 여러분이 제시한 조건을 만족할경우 설정해놓은 명령대로 처리하게 만들수 있는 것이 if의 주된 요지이다. 자바코드는 다음과 같이 이루어진다.

if (조건)
{
명령문1;
명령문2;
명령문3;
......
}

즉 조건이 true가 성립되면 중괄호 블록안의 명령문들이 차례대로 실행된다. 모든 제어문에서 { }는 안에 명령문이 한줄일 경우 생략이 가능하나 두줄 이상일 경우에는 중괄호로 묶어주어야 한다. 그럼 직접적인 예제를 통해서 if문을 살펴보겠다.


조건문에서 a가 10과 같으면 a와 b를 더하라는 프로그램이다. a가 10이니 더한값 30을 출력한다. 그럼 다음 예제를 살펴보자.


if문이 일단 두개가 있다. 첫번째 if문에서 조건을 검색한후에 참이면 안에 내용을 실행하고 아니면 다음 if문으로 넘어간다. 두번째 if문에서는 total이 20보다 작아야 참이 되므로 첫번째 if문에서 거짓이 나와 첫번째 명령문들이 실행되지 않아야 두번째 if문이 수행될수 있다. 프로그램을 짜고 결과를 생각해보고 자바를 실행해보기 바란다. 덧붙여 설명하자면 a가 10이고 b가 20이다. a가 10보다 크거나 같은지를 물으므로 true이고 b가 20보다 작거나 같은지를 물으므로 역시 true이다. 따라서 안의 명령문 두줄을 처리한다. 다음 total이 20보다 작냐고 물었는데 앞의 if문을 처리했으니 total값이 0이 아니라 현재 30이다. 따라서 두번째 if문은 처리되지 않는다. 그런데 이상하지 않나? 실행해보면 두번째 if문이 그것도 두번째줄이 처리된 것을 볼수 있다. 희한하다. 왜일까? 그렇다. 두번째 if문의 명령문은 첫째줄만 해당하지 둘째줄은 if문과 상관없이 프로그램을 실행하면 항상 처리된다. 이유는 { }. 아까 중괄호가 없는 제어문은 한줄만 명령문으로 인식한다 하였다. 까먹은 이들은 반성하자. -.- 이번에는 if else 구문을 공부해 보겠다.

if (조건)
{
명령문1;
...
}
else
{
명령문2;
...
}

즉 조건을 만족하면 명령문1을 실행하고 조건을 만족하지 못하면 명령문1 대신에 명령문2를 실행한다. 한마디로 양자택일이라 할수 있겠다. 다음 예제를 통해 if else 구문을 살펴보기로 하자.


위의 예제는 if문과 else문을 함께 적어놓은 것이다. 프로그램에 대해서 설명하자면 지금 지원자가 음대에 지원을 했다. 다른 과목은 점수가 미달하더라도 음악 점수만 80점을 초과하면 들어갈수 있는 학교다. 근데 지원자가 놀라운 성적으로 음악 과목만 88점을 획득하였다. 따라서 합격했다는 기분좋은 스토리(?)다. ㅎㅎ if문이 참이다. 따라서 else문은 처리하지 않는다. 지원자를 가상히 여겨 기왕이면 다홍치마 합격하는 걸로 만들었다.^^ 이해하는데 무리가 없을걸로 생각하고 다음으로 넘어가겠다.

이번에는 else if 구문이다. 당연하지만 첫번째 조건문은 if로 시작해야된다. 이 조건문은 해당하는 케이스가 나올때까지 조건을 검색하는 제어문이다.

if (조건1)
{
명령1;
...
}
else if (조건2)
{
명령2;
...
}
else if (조건3)
{
명령3;
...
} //원할시 여기서 끝내는 것도 가능하다.
else
{
명령; //위의 케이스 모두 해당사항 없을시 실행된다.
...
}

한마디로 조건이 참이 될때까지 검색해 보는 것이다. 이런 else if 조건문은 여러분이 원하는만큼 만들수 있다. 예제를 통해 어떤 프로그램을 만들수 있는지 살펴보기로 하자.


필자가 오래간만에 긴 프로그램을 만드느라 무리(?)한만큼 여러분도 그에 상응하는 시간을 투자해 본인의 것으로 만들기 바란다. 프로그램을 설명하자면 a라는 게이머가 미로게임하다가 4차관문까지 통과하고 함정에 빠져 게임이 끝나버렸다. a게이머가 게임하면서 받은 스코어(85점)를 토대로 결과를 출력하는 프로그램이다. 해당되는 조건이 있을때까지 검색하다가 해당사항이 있으면 그 해당 명령문을 실행하고 제어문을 빠져나오는 프로그램이다. 특별히 어려운 점은 없으리라 보인다. a값을 변경해 가면서 모든 조건을 다 만족하는지 살펴보기 바란다. 위의 결과값은 4번째 조건문을 만족하므로 아래와 같다.

4차 관문까지 통과하셨습니다.
게임을 종료합니다.^^

질문 있나? 어디 똑똑한 학생 질문 없을까? 허걱~ 질문 있어야 하는데...^^ 이 프로그램에는 아주 치명적인 에러가 하나 있다. 무엇일까? 궁금하면 50점 아래로 a값을 넣고 자바를 돌려본다. 황당하지 않은가? 택도 없는 점수를 넣었는데도 여러분이 게임지존이라고 나올 것이다. 즉 if를 비롯 else if까지 체크한 4가지 조건문 모두 만족하는게 없으므로 else를 실행하게 되는 것이다. 반대로 4가지 조건문 중에 하나라도 만족하는게 있으면 else 구문은 실행되지 않는다. 마지막에 else 구문을 써도 되지만 꼭 그럴 필요는 없다. 이런 경우 else 구문 대신에 else if 구문을 한번 더 쓰고 끝내버리면 해결된다. 아래글을 읽기전에 해결방법을 각자 모색해보기 바란다.

몇가지 방법을 제시해 보겠다. 물론 50점 아래 범위를 관계연산자를 써서 다른 케이스와 같이 a>0 부터 a<=50 까지 조건문을 만들어서 쓸수도 있을테고 새로운 변수를 하나 더 써서 아주 간단하게 넘어갈수도 있다. 어차피 점수가 50점 아래일 경우 마지막 케이스만 실행되지 않게 만들면 되니까 변수를 하나 써서(int b=0;) 마지막 else 구문 대신에 else if (b!=0) 구문으로 고쳐서 돌릴수도 있을 것이다. 물론 후자보다는 전자의 경우가 명료하고 정확하므로 전자를 선택하는 것을 추천한다. 후자는 프로그램이 길어지면 길어질수록 오류가 날경우 문제를 해결하기가 힘들어진다. 여기서는 기계적인 오류가 아니라 논리적인 오류가 났을경우 여러 해결방법이 있다는 것을 보여주기 위해 예를 들어본 것이니 많은 응용을 통해 오늘 배운 if 조건문을 마스터하기 바란다.

마지막으로 새로운 if else 구문을 소개하겠다. if else 구문을 축약형으로 ?와 :(콜론)을 이용해서 한줄로 표시할수 있는데 예제를 보면 한번에 이해가 갈것이다.

if (a > b)
  result = a;
else
  result = b;

위의 구문을 한줄로 쓰는게 가능하다.^^ 어떻게? 요렇게~
result = (a > b) ? a : b;

물론 a, b, result 세개의 변수는 int형이라고 선언했다고 하고 위와 같이 단 한줄로 축약해서 쓰는 것이 가능하다. 공식화해서 쓴다면 아래와 같이 생각해볼수 있을 것이다.
리턴값 = (조건문) ? 값이 true일 경우 : 값이 false일 경우;

물론 마지막에는 콜론이 아닌 ;(세미콜론)이 들어가야 한다.
또한 else if처럼 조건문을 더 달수도 있다.
리턴값 = (조건문)? 값이 true일 경우 : (조건문)? : 값이 true일 경우 : 값이 false일 경우;

이 정도 설명했으면 이해되었을테니 본 강의는 여기서 마치겠다.^^

2011년 4월 25일 월요일

자바의 논리연산자(&&,||)

논리야 놀자~^^ 오늘은 자바의 논리연산자인 &&(AND)와 ||(OR)의 기능에 대해서 알아보기로 하자.

A && B
A 그리고 B, A와 B가 모두 true일때만 그 결과도 true이다.
다른 말로, 어느 한쪽이 false라면 그 결과도 false이다.

A || B
A 또는 B, A와 B에서 어느 한쪽만 true라도 그 결과는 true이다.
다른 말로, 둘다 false라야 그 결과도 false이다.

위의 말만 이해하면 어떤 상황이 닥쳐도 저절로 다 이해가 될것이다. 자바의 논리연산자를 설명하기 위해 강이도 여러가지 도표나 수식들로 멋드러지게 폼(?)을 잡아보려고 했으나 자바를 열심히 공부하는 여러분을 위해 자제하기로 했으니 더욱더 분발해주기 부탁한다.

심층학습을 위해 아래 예제를 직접 쳐보고 결과가 어떻게 나올지 실행하기전에 생각해본다. 그리고 실행해서 맞춰보라. 다 맞았는가? 한두개 정도는 틀려도 실망할건 없다. 틀렸다면 위의 설명을 다시 한번 읽어보면 이해가 될것이다.
예제에서 &&나 ||인 논리연산자가 한번 나왔을때는 별로 어렵지 않았을 것이나 이게 두번 세번되면 가물가물해지는 경우가 있다. 허나 필자의 강좌를 숙지한 이들이 이 정도 레벨에 굴복(?)하지는 않을거라 믿는다.^^ 그럼 중요한 사항만 짚고 넘어가겠다.

예제에서 아래와 같은 구문이 있다.
System.out.println(10==10 && 10>20);

비교연산자와 논리연산자가 함께 있다. 괄호가 없어 애매모호할 것이다. 이렇게 비교와 논리가 함께 놀 경우 비교연산자 즉 관계연산자가 먼저 처리된다. 따라서 계산의 순서는 아래와 같이 될 것이다.

10==10 && 10>20
true && false
false

그럼 다음 &&(그리고, AND) 구문을 보자.
System.out.println((10<20) && (20<30) && (30<=40));

괄호까지 있으니 보기 편할 것이다. 관계연산자부터 차례차례 계산한 다음에 논리연산자 계산하면 된다. 20이 10보다 크냐고 물었으니 참이고 30이 20보다 크냐고 물었으니 참이고 40이 30보다 크거나 같냐고 물었는데 뭘까? 저번 시간에 배웠는데 모른다고 하진 않겠지? ^^ 거짓이 아니고 참이다. 40과 30이 같지는 않지만 크기는 하다. 따라서 한쪽이라도 맞으니 참이다. 한국말 참 어렵다.ㅎㅎ 순서대로 정리하면 다음과 같다.

(10<20) && (20<30) && (30<=40)
true && true && true
true

만약에 하나라도 false가 나왔으면 답이 false일텐데 그냥 찍어도 맞출수 있는 문제를 낸것 같다.ㅋㅋ 그럼 이제 ||(또는, OR) 예를 보자.

System.out.println(10!=20 || 10>20);

아까 배운대로 관계연산자부터 처리한다. 10과 20이 같지 않은게 맞는지 묻는거다. 같지 않으면 true, 같으면 false가 된다. 저번 강좌에서 이 부분을 무지 강조했으니 틀리는 이가 없길 바라면서 다음은 당연히 10이 20보다 크지 않으니까 false이다. 그러면 첫번째는 숫자가 같지 않으니까 true이고 두번째는 20이 더 크니까 false이다. OR 구문이므로 전체는 한쪽만 맞으면 되니까 true이다. 잠 깨라고 표현을 일부러 이리저리 돌려가면서 쓰고 있다. 정신 바짝 차리면 이해될꺼다.^^

System.out.println((10>20) || (20>30) || (30<=40));

자, 조금만 더 하자. 마지막이다. 거침없이 하이킥(?)이다. 첫번째는 10이 더 크지 않으니까 틀렸고 두번째도 20이 더 크지 않으니까 틀렸고 세번째는 30이 40보다 작은건 맞는데 30이랑 40이랑 같냐고 물으니 당연히 아니니까 틀렸고 따라서 답은 다 틀렸으니 당근 false다. 이렇게 답 내는 이가 있으면 완전 실망 --, 마지막에 30이 40보다 작은게 맞으니까 다른거 볼것도 없이 참이다. 관계연산자 두개가 같이 나오면 한쪽만 맞아도 참인 것이다. 또한 OR 구문이므로 전체 정답도 true이다. 딴거 다 틀렸어도 마지막게 맞았으니 참이 된다. 이것이 바로 || 의 매력인 것이다.

맨위에 간략하게 &&와 ||의 정의를 썼지만 그래도 어려워하는 이들을 위해 오직 하나, 단 한줄로 심플하게 자바의 논리연산자를 요약해 보겠다. 잠시나마 무한감동(?)을 느끼기 바란다.

&&
하나라도 틀리면 가차없이 false

||
하나라도 맞으면 무조건 true

오늘의 핵심사항은 위의 두줄이다. 고작 이 두줄 갖고 이렇게 오래 설명했다고 필자를 탓하는 이(?)는 절대 없어야 할것이다. 왜냐? 여러분이 자바를 접하는 동안 이 두줄이 여러분을 주구장창 먹여살릴 것이기 때문이다. ^^ 그럼 끝내기에 앞서 예제의 결과값을 공개한다. 그냥 맞춰보지만 말고 자바로 꼭 본인이 직접 실행해 보기 바란다~

AND 예제
true
false
false
false
true

OR 예제
true
false
true
true
true

자바의 관계연산자(==, !=, <, >, <=, >=)

* 결과값은 맨뒷장에서 보여줄 예정이니 미리 보지말것!

이번에는 자바의 관계연산자(==, !=, <, >, <=, >=)에 대해서 알아보겠다. 일단 위의 프로그램을 짜면서 실행하기전에 어떤 답이 나올지 미리 생각해보기 바란다. 관계연산자는 여러분이 잘아는 서로 크고 작음을 비교를 하는 연산자인데 비교를 하는거니까 당연히 뭔가를 물어보는 조건문에서 많이 사용되며 결과값으로 boolean타입 즉 참(true)이나 거짓(false)을 알려준다. 관계연산자 혹은 비교연산자 다 같은 말이다.

a == b, a와 b가 같니?
a != b, a와 b가  같지 않지? 네^^ 같지 않아요. (같지 않으면 true, 같으면 false)
a < b, b가 a보다 크니?
a > b, a가 b보다 크니?
a <= b, b가 a보다 크거나 같지 않니?
a >= b, a가 b보다 크거나 같지 않니?

관계연산자를 이용하면 크게 위와같이 6가지 형식으로 질문을 하는것과 같다. 너무 쉬워서 서서히 졸려울거다.ㅎㅎ 그래서 준비했다. 이것은 무엇일까?

!(1==1)

참일까 거짓일까? 답을 생각해보고 위의 질문을 자바에 넣고 한번 실행해 보자. 물론 자바에 넣을때는 이렇게 넣으면 된다.

System.out.println(!(1 == 1));

괄호가 많으니 정신(?)없을지도 모르겠다. 저번에도 언급한적 있지만 중간에 띄워쓰기나 빈줄은 자바에서 인식하지 않으니 연산부호 양옆을 띄워서 쓰면 보기 편하다. 이런 표현방식이 때때로 쓰이는데 확실하게 알아두지 않으면 혼동하기 쉽다. 이걸 명확하게 푸는 비책(?)을 소개한다.

!(1==1)
1 == 1, 1이랑 1은 같으니까 true
!(true), true를 아니라고 틀렸다고 말하니까 false

위와같이 고수들만 떠올린다는 삼단논법(?)으로 해석해나가면 이런 조건문을 만나도 겁먹을 필요가 없다. 즉, 괄호부터 처리하면 된다. 이제 비책을 얻었으니 테스트 삼아 아래를 실험해보기 바란다.

!(1!=1)

모르면 항상 정답을 알려주는 자바를 돌려보도록 한다. 위에서 보충 설명하였지만 이 부분은 상당히 틀리기 쉬운 부분이다. 1과 1이 같으니까 무심코 자기도 모르게 참(우리말에서 강조형으로 묻는 "그렇지 않니?"의 의미가 아니다.), 그 다음에 그것을 부정하니까 거짓, 따라서 답을 false라고 말하는 이가 생각보다 많을 것이다. 허나 정답은 true다. 같지 않은지 물었는데 같지 않아야 참이다. 허걱~ 이것을 맞춘 똘똘한 이가 그래도 한명(?)쯤은 있었길 빈다. 여기서는 숫자가 1과 1 즉 값이 같다. 따라서 처음에 false가 된다. 그 다음에 !(false)를 구하는게 된다. 그러면 true가 나온다. 프로그램 짜면서 순간적으로 실수하기 쉬운 부분이니 확실히 알고 넘어가기 바란다.

!(1<=1)

기호 많으니까 어려워 보이남? 필자가 비책을 선물로 주었는데 무슨 걱정을 하는가? 아끼지 말고 쓰도록 해라. 안쓰면 썩는다. ㅎㅎ

1<=1, 1이 1보다 크거나 같니? 한쪽만 성립하면 참이다. 따라서 참이다.
!(true), true가 아니라면? 당연히 거짓이 된다.

자 그럼 이제는 직접적으로 물어보겠다. 이렇게 물으면 또 가슴철렁하는 이가 있더라.

!!!true

답이 뭘까? 비책을 울어먹어라. 다를게 하나도 없으니까 말이다. 답은 false (true의 반대, 반대, 그리고 반대는?) 이렇게 묻는것과 같다. 설마 ! 이거 많아가지고 아 복잡하다 그러는 사람은 없겠지? 그래도 혹시나 몰라 이것도 골이 아파서 못하겠다는 이들한테 필자가 또 하나의 비기(?)를 선물하겠다. 잘 들어라. "홀수면 반대로, 짝수면 원래대로"다. ! 많을때 아주 빨리 계산하는 필자만의 비기이니 많은 이들에게 널리 퍼뜨려 자바 세상을 이롭게 하라. ㅎㅎ

마지막으로 하나만 더 주의깊게 살펴보자.

a = b
a == b

위의 두가지가 똑같은 의미라고 생각하면 큰 오산이다. 소스를 짜다보면 자기도 모르게 혼동하는 이들이 있는데 첫번째는 변수 a에 변수 b의 값을 넘겨주라는 얘기고 두번째는 변수 a와 변수 b의 값이 같다는 의미다. 이번 시간 이후로 이 부분에 대해서는 착각하는 이가 없길 바란다.

자, 오늘은 조건문에서 시도때도 없이 쓰이는 관계연산자에 대해서 알아보았다. 저번에 배운 "증감연산자", 이번에 배운 "관계연산자", 그리고 다음에 배울 "논리연산자"는 결과값을 도출해내기 위해 테스트할때 자바에서 아주 많이 쓰이는 부분이니 자유자재로 써먹을수 있도록 열심히 익히기 바란다. 그리고 맨위에 보여준 예제의 결과값은 아래와 같다.

true
false
false
true
false
true
=====
false
true
false
true
false
true

2011년 4월 24일 일요일

자바의 증감연산자(++,--)

오늘은 자바의 증감연산자(++,--)에 대해서 알아보겠다. ++는 변수의 값을 1씩 증가시키고 --는 변수의 값을 1씩 감소시킨다. 그럼 아래 예제를 보자.
증감연산자를 이용해서 값들을 출력하는 예제이다. 특별히 어려운게 없으니 다 이해했으리라 본다. 굳이 설명하자면 a랑 c가 같고 b랑 d가 같다. 값이 같은게 아니고 a랑 b의 연산방식을 풀어서 쓴것이 c랑 d이다. 출력부분에서 +는 변수 때문에 쓴것이지 더하라고 쓴것이 아님을 다들 기억하고 있으리라 믿는다. 믿어도 되겠지? ^^

그럼 이번에는 많은 이들이 헤깔려하는 예제를 보여줄까 한다. 실행하기 전에 결과값을 예상해보고 자신의 생각과 맞는지 점검해 보기 바란다.
증감연산자를 뒤에다 놓고 쓸수도 있지만 앞에다 놓고 쓸수도 있다. 계산값은 둘다 똑같으나 위의 예제에서처럼 그 값을 다른 변수에 넘겨줄때는 약간의 차이가 있다. 무엇이 다를까? 한마디로 시간차 패스(?)라고나 할까나? ^^ 그럼 결과값을 보면서 설명하겠다.

a=2
b=2
c=1
d=2

a랑 b는 어차피 1씩 더한거니까 2가 나올줄 다 예상했을꺼다. 설마 1이라고 답변한 사람은 없겠지? 진심으로 없길 바란다. ^^ 1+1=? 뭘까?  2 잖어...뭘 그렇게 오래 생각하셤? ㅎㅎ 자 우리가 알아야될 부분이 c와 d인데 c가 1이다. 증감연산자를 변수뒤에 써놓으면 계산하기전의 값을 넘겨주고 1을 증가시키고 반대로 증감연산자를 변수앞에 써놓으면 계산하고난후 즉 1을 더하고난 후의 값을 넘겨준다. 왜 이런걸 만들어났지? 싶을거다. 때에 따라서 유용하게 쓰일때가 있다. 은근히 헤깔리므로 지나치기가 쉬운데 외우기 쉬운 방법을 특별 공개(?)한다.

1. 증감연산자에 있을시 반대로 계산하고난 의 값을 해당 변수에 넘겨준다. (변수가 뒤에 있을시 후처리) ++b
2. 증감연산자에 있을시 반대로 계산하기 의 값을 해당 변수에 넘겨준다. (변수가 앞에 있을시 선처리) a++

앞뒤 전후 거꾸로 생각하면 외우기 쉽다. 1번(예제에서는 b의 경우)을 유식한 말(?)로 하면 "선 연산, 후 처리"라고 하고 2번(예제에서는 a의 경우)을 유식한 말(?)로 하면 "선 처리, 후 연산"이라고 한다. 노파심에 한마디 더하자면 "처리"하는 부분이 해당값을 변수에 넘겨주는 부분이다. 자꾸 같은 얘기하니 오히려 더 헤깔릴지도 모르겠다.ㅎㅎ

a--;
--a;
a-=1;
a=a-1;
네가지 다 a값을 1씩 감소시키라는 뜻

a++;
++a;
a+=1;
a=a+1;
네가지 다 a값을 1씩 증가시키라는 뜻

증감연산자, 특히 1씩 더하는 증감연산자(++)는 자바에서 약방에 감초처럼 엄청 많이 쓰인다. 따라서 네가지 방식 모두 무조건 암기하라. 네가지 중 마지막것이 의미가 확실해서 모든 프로그래머들이 그렇게 쓰면 좋겠으나 대부분 처음것을 사용한다. 워낙 많이 쓰이니 매번마다 쓰기 귀찮아서 이런게 개발(?)되었다. 자바의 발전은 계속될 것이다.ㅎㅎ 다음 시간까지 확실히 하라고 더 이상 진도 나가지 않겠으니 열심히 외우자. ^^

자바의 변수와 상수(Variable & Constant)

이번 시간에는 변수(variable)와 상수(constant)에 대해서 알아보기로 하자.

a=0;

a는 다른 값으로 변경시킬수 있다. 이렇게 변하는 수가 변수이고 0처럼 항상 같은 수 변하지 않는 수를 상수라 한다.

b=true;

숫자가 없으니 조금 어려운가? b가 변수이고 상수는 true이다. 참과 거짓을 표시하는 키워드가 있는데 참을 true로 거짓은 false로 표시한다. 자바를 비롯한 대부분의 프로그래밍에서 맞는지 틀리는지 검사할때 사용하는 키워드이다. 이런 자료형을 boolean 타입이라고 하는데 컴퓨터 전산이나 전자공학에서 숫자 1과 0을 사용하여 참인지 거짓인지를 구분할때 많이 쓰이는 방식이 바로 불린 타입이다.

변수 본김에 이름 짓는 규칙에 대해서 다시 한번 상기시키겠다. 저번에 언급한데로 메소드는 첫 글자를 소문자로 시작하고 클래스는 대문자로 시작한다. 또한 변수도 첫 글자를 소문자로 시작하며 연결되는 단어 첫글자에만 메소드처럼 대문자로 쓰는 것이 관례다. 그리고 이름을 지을때 public void static class true false 같은 자바에서 사용하는 키워드로 이름을 지을수는 없다. 명령어와 구분해야되니까 말이다.

그럼 변수와 상수를 이용해서 간단한 예제를 실행해 보기로 하자.
a랑 b의 경우 결과가 어떻게 나오는지 보았으면 아주 시시하게 생각할수도 있고 아니면 신기하게 생각할수도 있겠다. 시시하게 보는 이들은 true랑 false를 그대로 입력하였으니 찍히는게 당연하다고 생각하는 쪽일테고 신기하게 생각하는 이들은 String 즉 문자형이 아닌데도 출력하는게 신기하다고 생각할 것이다. 여러분은 후자이길 바란다.^^ true랑 false는 그냥 문자가 아니라 자바에서 참과 거짓을 판단하는 boolean형의 키워드이다. 따라서 특별한 조치(?)없이 저렇게 참거짓을 출력할수 있다. String 타입인 s랑 비교를 하면 이해가 쉬울 것이다. boolean형은 나중에 여러분이 배우게될 조건문에서 수시로 보게 될것이니 기대하시라.-

c와 d는 한마디로 정수 즉 소숫점이 없는 경우와 소숫점이 있는 경우의 차이라고 알아두면 된다. 위와 같이 c나 d같은 변수를 쓰려면 자료형을 먼저 자바에게 알려주어야 한다.

int c;
double d;

위와 같이 자료형을 정의해 주지 않으면 그 변수값에 뭐가 어떤 형태로 들어갈지 자바에서 준비를 해놓을수가 없으므로 에러가 난다. 위의 예제에서는 자료형은 자료형데로 입력값 넣을때랑 결과값도 마찬가지로 종류별로 분류해 놓았다. 별거 아닌듯 하나 정리를 이렇게 잘해놓으면 코드가 길면 길수록 빛을 바란다. 프로그램 전체를 한눈에 알아보기 쉽고 변수 관련 부분이나 출력 관련 부분을 다시 찾아볼때  시간을 줄일수 있어 상당히 편하다. 물론 여러분이 원할시 int c=0; 이런 형태로 두 줄을 한 줄로 바꿔서 쓸수도 있다. 이런 경우는 자주 쓰이는 변수보다는 임시로 변수가 필요할시 보통 사용한다.

s는 아까 언급했으니 알것이고 마지막으로 o에 대해서 설명해 보겠다. 사실 s랑 결과가 같은데 달라보이니 재미(?)있을 것이다. 아니면 말구~ ㅎㅎ String 클래스를 이용해 o라는 객체를 생성해서 이렇게 문자를 찍을수도 있다.

String o;
o=new String("how are you?");

String o=new String("how are you?");

위의 예제는 첫번째 방식을 택했는데 두번째꺼랑 같은 말이다. 이거야 프로그래머(?) 역량에 따라 선택해서 쓰는데 객체 생성을 여러개 하면 모를까 그렇지 않다면 s변수처럼 객체 생성없이 그냥 문자를 받아들이는 경우도 있으니 두번째 표현방법이 한눈에 알아보기가 더 쉬울 것이다. 예제는 본인이 직접 타이핑해서 실행해 보기 바라면서 그래도 혹시 여태까지 기다려온 끈기있는 회원들(?)을 위해 결과값을 특별히 공개한다. 결과보고 땡치지 말고 반드시 직접 해보기 바란다. ^^

true
false
0
1.2345
hello
how are you?

Scanner를 이용한 문자열 입출력 예제

오늘은 예고한데로 Scanner 클래스를 이용한 문자 입출력 예제인데 설명에 앞서 위의 코드를 에디터에 치고 실행부터 해보기 바란다. 잘 작동하면 오히려 이런 반문이 생길 것이다. 진작 이걸로 알려주지 헤깔리게 다른거 보여줬냐고 말이다. 배우는게 힘이다. 모르면 몸이 고달프다. ^^ 이렇게 같은 값을 얻더라도 그 과정은 다를수 있다는걸 알려주기 위한 예제이니 어떤 프로그램이든 기왕이면 좀더 효율적으로 값을 얻어내는 방법이 있는지 항상 탐구하는 자세를 갖기 바라면서 이제 본격적으로 코드 설명을 시작해 보겠다.

일단 맨 첫줄에서는 Scanner 클래스를 쓰기 위하여 import 해왔다. 이 클래스는 java.util 패키지에 들어있는데 util 이라는 말에서 짐작할수 있듯 편리한 기능들이 많이 있으니 심심할때 한번씩 들여다보기 바란다. 어디에서? jdk api 문서에서... 이미 저번에 설명한바 있으니 어떻게 찾는지는 생략하겠다.

클래스 Test4에 메인메소드가 들어있는데 안에 무슨 내용이 있는지 살펴보자. 처음에 보이는 구문은 Scanner 인스턴스를 만들면서 입력값(System.in)을 받을 준비를 하라는 뜻이다. 그리고 마지막에 sc.next() 메소드는 그 인스턴스를 이용해 받은 문자를 처리하는 것이고 말이다. 더 설명할게 없네. 끝이다. 허걱~ 너무 간단한가? 아쉬움을 달래기 위해 조금 더 설명하자면,

String s=sc.next();
System.out.println(s);

System.out.println(sc.next()); 이 라인은 위의 두 라인과 일맥상통한다. 어느쪽이든 좋은 쪽으로 쓰기 바란다. 그런데 위의 자바소스는 띄워쓰기를 허용하지 않으므로 한 단어 밖에는 입출력할수 없다. 그럼 라인 전체를 입력받아서 출력할수는 없을까? 하는 의문이 생길지도 모르겠다. (생겼길 바란다. ^^)

딱 하나만 바꿔주면 된다. 바로 next() 를 nextLine() 으로 바꾸어주면 띄워쓰기 몇번을 해서 입력하든 상관이 없다. 즉, 문자열을 출력하길 원하면 nextLine() 메소드를 이용하면 되는 것이다. 지금 이 예제는 문자열이므로 숫자나 문자나 상관이 없지만 숫자만 받아들이게 만들수도 있다. 그럴 경우 next() 대신에 nextInt() 메소드로 교체해주면 숫자만 입출력할수 있게 만들어준다. Int 는 당근(?)이지만 integer를 뜻한다. 라이브러리에 이처럼 다양한 메소드들이 있으니 이해가 되든 안되든 눈에 익도록 자주 들여다보기 바란다. 언젠가 써먹을 날이 있을 것이다.^^

마지막으로 저번 입출력 예제와 이번 입출력 예제에서 크게 다른 점이 하나 남아있다. 혹시 발견한 똑똑한 이(?)가 있다면 손들어봐라. 과연 있을까? ㅎㅎ 숨은그림찾기에 가까운데 아직 발견 못했으면 다시 한번 찾아보고 정답을 들여다보기 바란다. 둥둥~두두둥~~ 그것은 바로 입출력 예외처리(IOException)를 할 필요가 없다는 것이다. 허걱~ 이럴수가! ㅎㅎ Scanner가 마술사라서 그렇다.^^

2011년 4월 23일 토요일

키보드에 문자열 입력받아서 화면에 출력하기


오늘은 클래스 Test3를 통해서 문자열을 출력하는 방법을 알아보기로 하자. 위의 보이는 소스를 지금 빨리 치고 실행해 본다. 하지도 않고 그냥 설명만 읽으려는 게으른 이들(?)이 없길 바라면서 본격적인 강좌를 시작하겠다. 저번 시간에는 문자 하나를 키보드로 입력받아 출력시키는 예제를 살펴보았다. 무슨 차이가 있는지 나름대로 비교해서 생각해 보도록 해라. 10분 줄테니 끝나면 다음 단원을 계속해서 보기 바란다.

문자열을 읽어드리기 위해선 저번에 설명한 System.in.read() 명령어로는 부족하므로 문자열을 읽을수 있는 다른 클래스들이 필요하다. 특히 필자가 저번 강좌에서 컴퓨터 프로세스에서 이루어지는 입력과 출력 부분을 풀어서 설명하였는데 그 과정이 이번에 InputStreamReader라는 클래스와 BufferedReader라는 클래스를 통해 적나라하게 나타날 것이니 코드가 조금 길어졌지만 이해하는데 큰 무리가 없을 것이다.

자, 그럼 본격적으로 코드를 해석해 보도록 하자. 일단 예제 클래스 Test3 에서 필요한 클래스들을 불러와서 써야한다. 총 4개의 클래스가 필요하며 그 중에 System 클래스는 자동적으로 자바에서 포함되므로 이를 뺀 나머지 클래스는 총 3개 즉, InputStreamReader, BufferedReader, IOException 클래스가 되겠다. 이중 IOException 예외처리 부분은 저번 시간에 설명하였으니 또 이를 빼면 달랑(?) InputStreamReader와 BufferedReader 클래스만 써먹을줄 알면 만사 ok다. 갑자기 마음의 짐을 덜지 않았나? ㅎㅎ

이해를 돕기 위해서 영어공부를 잠시 하겠다. "stream (수많은 일의) 연속이나 이어짐" 이런 뜻을 가지고 있는데 개울이나 시내란 뜻도 있는걸 보니 계속해서 흘러가는 길이 있어 이런 뜻으로 해석되는듯(?)하다. 여기서도 그런 관점에서 봐도 무방하겠다. 입력장치(키보드)에서 출력장치(모니터)로 데이터를 보내야하는데 이 중간에 길이 있어야한다. 그 역활을 InputStreamReader가 해주고 있다라고 생각하면 된다. 그리고 buffer는 사전에서 찾아보면 완충제, 완충장치라는 뜻이 가깝긴 한데 그보다는 각 장치나 프로세스에서 공유되는 데이터를 저장하는 공간이라고 해석하면 더 이해하기가 쉬울 것이다. 다시 연결해서 설명하자면, 키보드에서 받은 값을(readline()) 입력장치 버퍼에서 일단 기억해놓고(System.in이 버퍼기능을 수행) 받은 데이터를 스트림을 통해 보내(InputStreamReader) 출력장치 버퍼에서 다시 데이터를 읽어들여(BufferedReader) 여러분의 모니터로 송신하는 과정이라고 말할수 있겠다. 이해가 쉽도록 반어거지(?)로 말을 만들긴 하였지만 이해하는데 무리는 없을거라 생각한다.^^

그럼 돌아가서 다시 코드를 보자. 코드는 이해하기 쉬우라고 일련의 과정들을 순서대로 정리해서 쓴것인데 이번에는 단적으로 심플하게 핵심코드만 보기로 하자.


System.out.println("문자 한줄을 입력하고 엔터를 누르시오.");
String s=br.readLine();
System.out.println("입력한 문자열은 "+s+"입니다.");

키보드 입력받아서 컴퓨터가 처리하고 모니터에 출력한다. 이 세가지 과정으로 압축된다. 즉, 여러분이 어떤 문자열을 입력했을때 readLine() 메소드로 읽어드린후


InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);

아까 위에서 설명한 것처럼 버퍼와 스트림을 통해 읽어들이는 것이다. 재탕(?)하자면, 키보드에서 readLine() 메소드로 읽어들인 문자열을 System.in객체에서 하나하나 스트림(isr)을 통해 연속적으로 보내진 데이터를 버퍼(br)에서 읽고 화면으로 그 데이터(s)들을 출력한다. 지금 위의 두 라인은 new가 있으므로 알다시피 입력값을 이용해 각 클래스의 객체를 생성하고 있는 과정이다. 이런 과정을 통해 얻어진 최종 버퍼값(br)으로 화면에 겨우겨우(?) 데이터(s)를 출력하게 만드는 것이다.

우리는 프로그래밍을 배우고 있다. 따라서 똑같은 정답은 없다. 여러분의 생각에 따라 결과는 같더라도 과정은 달라질수 있다. 이게 프로그래밍을 배우는 묘미라면 묘미일수 있겠다. 오늘 버퍼와 스트림을 이용한 입출력 방법을 간단하게나마 알아보았다. 다음 시간에는 입출력의 마술사 Scanner 클래스와 만나는 시간을 통해 그 진한 감동의 묘미(?)를 느껴보시기 바란다. ^^

2011년 4월 22일 금요일

키보드로 글자 입력해서 화면에 출력하기


예제는 마우스로 클릭하면 확대된다. 안보인다고 항의하지 말자.^^
저번 시간에 우리는 원하는 내용을 자바 소스에다가 써서 화면에 출력시켜 보았다. 그러면 이번에는 미리 써놓지 말고 키보드로 원하는 값을 입력받아서 화면에 그 내용을 출력시키는 방법을 이번 시간에 알아보도록 하자. 자바를 이제 시작하는 이들은 상관없을 것이나 다른 자바 강좌나 교재를 공부해본 이들이라면 상당히 의아해 할 것이다. 자바의 입력에 관련된 부분은 대부분이 중간 이후에 언급하기 때문이다. 그런데 필자는 초반에 버젓이 입력부분을 건드리려 한다. 왜일까? 이유는 없다. 그건 여러분이 지금껏 본 강좌를 충실히 따라왔다면 가능할 것이라고 보는 믿음(?) 오직 그 믿음뿐이다.ㅎㅎ

출력을 했으면 입력은 어떻게 하는지 궁금한 것이 당연지사일 것이다. 허나 부분적으로 초반에 설명하기에는 난감한 부분들이 튀어나오기 때문에 보통 다른 곳에서는 나중으로 미루는데 필자는 그냥 정면돌파한다.^^ 메인메소드 공략에 성공한 여러분이라면 이번 내용도 무난하게 소화하리라 생각한다. 일단 위의 코드를 입력하고 실행해 본다. // 로 표시된 부분은 여러분의 이해를 돕기 위해 필자가 주석을 달아놓은 것이다. 따라서 굳이 타이핑 할 필요는 없다. 앞으로도 코드를 빠르게 해석하라고 저렇게 코드 옆에 설명을 달아볼까 한다. 좋냐? 침 닦아라. ^^

자 이제 본격적으로 위의 코드를 설명해 보겠다. 실행해 보았으면 어떤 내용인지 대충 감을 잡았을 것이다. 한 글자를 입력받아서 그 글자를 화면에 출력하는 예제이다. 위에서부터 차근차근 살펴보자. import 라고 되어있는 부분은 저번 시간에 필자가 설명을 했다. 필요한 클래스를 쓰기 위해서 다른 곳에서 가져온 것이다. 주석 달아놓은데로 클래스 일일이 쓸 필요없이 *표시를 이용해 한줄로 만들어도 상관이 없다. 이런 클래스들은 어디에 있고 어떤 순서로 있는지 궁금할지 모르겠는데 여러분이 자바를 설치했을때 설명서에 다 들어있는 내용이다. 자바 에디터를 사용하고 있다면 JDK Help나 JDK API 같은 버튼을 찾아 클릭해 보면 여러 패키지들을 볼수가 있는데 위의 써놓은 패키지들의 경로대로 찾다보면 나올 것이다. 에디터가 없는 이들은 자바 설명서를 자바 프로그램 메인폴더에 넣어놨다면 docs라는 폴더가 보일 것이다. 안으로 들어가면 api라는 폴더가 있는데 그 안에서 index.html을 클릭하면 여러 자바 패키지들을 찾아볼수가 있다. 우리는 이곳을 자바 라이브러리(library)라고도 한다. 도서관처럼 자주 찾으니까 말이다.

다시 프로그램으로 돌아와서 Test2 라는 이름의 클래스이니 파일이름도 당연히 똑같아야 할것이다. Test2.java 메인메소드를 찬찬히 살펴보면 다른 용어가 끝에 하나 보인다. throws IOException 이라는게 보이는데 처음 보았다고 겁먹지 말고 우리가 배운 노하우(?)를 적용해 해석하려 애를 써보기 바란다. throws 무슨 뜻인가? 뭐 던지다라는 뜻이다. 뭐를 던지나? IOException을 던지라고 한다. 그럼 IOException은 무엇인가? 글자에서 느껴지는게 없나? 호오~ 이제는 빨리 반응이 오는구나. 그렇다. 대문자로 시작함에서 역시 예상할수 있는 것은 IOException이 클래스라는 점이다. 클래스를 사용해야되므로 위에서 import라는 명령을 이용해 java.io 패키지를 불러온 것이다. 그럼 IOException 이라는 영어철자를 낱낱히 파헤쳐보자. IO+Exception = InputOutput+Exception = IOException 이제 감이 팍팍 오리라 믿는다. "input입력" "output출력" "exception예외" 필자가 영어공부까지 시켜주니 이보다 더 좋을수 있으랴. ㅎㅎ 즉, 입출력에 관한 예외를 던져버리라는 뜻인데 입출력에 관한 예외가 여기서 발생했을시 다른데로 보내라는 것이라고 해석하면 이해가 쉽겠다. 자바에서는 입출력에서 발생될지 모르는 에러들을 미리 예외처리를 해놓으라고 되어있다. 사용자가 뭘 입력할지 누군들 알겠냐(?)ㅎㅎ 이런 예외처리는 메소드 옆에 throws 라는 명령어를 통해 예외처리할 클래스를 지정하고 위와같이 사용하면 된다.

System.out.println("중얼중얼");은 저번에 설명했으니 알 것이고 다음줄의
int c=System.in.read(); 가 조금 어려울텐데 뜻은 이러하다. 설명전에 조금 뜸을 들이겠다.
위의 줄은 아래 두줄과 같은 뜻이다.
int c;
c=System.in.read();
이러면 이해가 쉬울지 모르겠다.
일단 int 는 "integer 정수"라는 뜻의 약자로 숫자를 뜻한다. 그리고 다음줄은 System 클래스를 이용해 in으로 그리고 read()라는 메소드를 이용해 키보드에서 사용자 입력값을 받으라는 뜻이다. 그 받은 입력값은 c라는 곳으로 보내지는데 여기서 =의 의미는 같다라는 의미보다는 컴퓨팅에서 관련값을 왼쪽 변수에 집어넣으라는 의미와 일맥상통한다. 키보드로 받은 값이 뭐가 될지는 모르지만 하여간 한 문자를 c에다가 넣고 뭔가를 하라는건데 뭔지 다음줄을 살펴보기로 하자.

System.out.println("입력한 문자는 "+(char)c+"입니다.");

이미 필자가 주석을 달아놓았지만 안의 내용이 조금 복잡해 보일 것이다. 차근차근 살펴보자. 괄호 양쪽 끝에는 따옴표가 있는데 안을 보니 또 따옴표가 있어 헤깔릴 것이다. +를 일단 주의깊게 보도록 한다. 자바에서 위의 System.out.println() 명령어를 통해 실행할시 문자열을 미리 써놓을수도 있지만 미리 써놓을수 없는 부분이 생겨나게 된다. 즉, 키보드로 사용자에게서 입력받을 c라는 값은 지금 현재로서는 사용자가 뭘 입력할지 모르니 미리 써놓을수가 없다. 따라서 값을 모르는 그런 변수를 출력해야 될때는 저렇게 미리 안내글 같은 문자열과 만나는 변수 양옆에다 +기호를  쓴다.

그럼 변수 앞에 있는 (char)은 무엇일까? char은 character의 약자로 저렇게 괄호로 앞에 있을때는 저 형태로 변환시키라는 이야기다. 어려운 말로 캐스팅(casting)이라고 한다. 여러분이 키보드로 입력한 값은 숫자를 치던 문자를 치던 자바는 컴퓨터 기호값으로 처리해서 읽어드리는데 이 값이 숫자이므로 c는 int 형태로 그 값을 받아야한다. 물론 사용자로부터 입력값을 맨처음에 받아들이는 read() 메소드도 결과값이 int 타입이니 c가 넘겨받을때도 당연히 int 타입이어야 한다. =이 성립하려면 양쪽부분의 자료형태가 똑같아야 한다. 너무 당연한가? 막상 말하니 어색하군.^^* 다음에 여러분이 입력한 값을 그대로 출력하려면 컴퓨터 기호값으로 읽어드린 것을 다시 여러분이 입력한 문자 형태로 만들어줘야 하는데 그 기능을 담당하는 것이 (char)를 이용한 캐스팅 기능이다. 즉, 읽어드린 int 타입의 컴퓨터 기호값을 다시 여러분이 입력했던 문자 형태로 되돌리라는 뜻이다. 이해가 잘 안되였다면 아래의 예제를 프로그램에 넣고 돌려보면 저절로 터득하게 될것이다.

System.out.println("입력한 문자는 "+(char)c+"입니다.");

System.out.println((char)c+"라고 입력하셨습니다.");
System.out.println("입력한 문자는 바로 "+(char)c);
System.out.println(c);

c가 문자열 앞쪽에 있을때랑 뒤쪽에 있을때 그리고 문자열이 없을때 +의 위치와 존재유무를 알게끔 써놓은 예제이다. 또한 맨 마지막 명령어를 통해서 문자로 캐스팅하지 않았을때는 컴퓨터가 여러분이 입력한 값을 어떻게 받아들이는지 알수 있을 것이다. 지금 이 자바 소스는 여러분이 입력하는 문자 하나만 받아들이고 출력하는 예제이므로 문자 여러개치고 엔터눌러도 맨 앞에 있는 문자 하나만 처리하니 착오없기 바라고 문자열을 받아들이는 예제는 말나온김에 다음 시간에 배워보겠다.^^

2011년 4월 21일 목요일

화면에 문장을 출력하기

public class Test1
{
public static void main(String[ ] args)
{
System.out.println("");
System.out.print("나는 클래스 Te");
System.out.print("st1의 메인 ");
System.out.println("메소드야.");
System.out.println(" ");
System.out.print("모든걸 총괄하는");
System.out.println(" 곳이지.");
System.out.println();
System.out.println("모두들~ 방가 방가^^ ");
}
}

Test1이라는 자바소스를 계속 붙들고 있는데 오늘은 기필코 이 프로그램 공부를 끝내도록 하겠다.^^ 메인메소드 안에 여러가지 쓰여있는데 다 비슷비슷해 보인다. 저번 시간에 메인메소드에 대해서 설명하였으니 이제 본격적으로 안에 있는 코드를 들여다보자.

System.out.println 이라는 문구와 System.out.print 이라는 문구가 대표적으로 달라보일 것이다. 여기서 딴 얘기를 잠깐 하겠다. 왜 쩜(.)을 찍는지에 관해서 말이다. 우리가 인터넷 도메인을 주소에 칠때도 뭐뭐 쩜 뭐뭐 닷(쩜) 컴이라고 쓰지 않나? 즉, 쩜이란 어디서부터 어디까지를 나타내주는 일종의 경로라고 생각하면 이해하기가 쉽다. 컴퓨터상에서 여러분이 디렉토리를 만들어본 적이 있을 것이다. 그리고 안에다 또 디렉토리를 만들고 이러면 경로를 여러분이 맨 바깥 디렉토리를 만든 것에서부터 안으로 들어가면서 나타나는 안쪽 디렉토리들과 구분을 쉽게 하기위해 \표시로 주소창에 나타나는 것을 보았을 것이다. 인터넷 주소도 사실 그러한 원리로 경로를 쩜을 찍어서 나타내고 있는 것이다. 다른 개념이 있지만 여기서도 지금은 똑같이 이해하기 바란다. 한꺼번에 너무 많은걸 알려고 하지 말아라. 다친다.^^ System이라는 곳에서 out으로 그리고 println 이나 print 로 도달해서 명령을 전달한 것이다. 물론 최종 종착지는 print 구문이니 뭔가를 출력하려는 것을 우리는 직감(?)으로 알수 있을 것이다.

그럼 다시 코드로 돌아가서 System을 보니 뭔가 느끼는게 없는가? 여기서 뭔가 느껴지면 그대가 정말 대단하게 보일텐데 말이다. 누군가 찾아냈기를 바라면서 설명하겠다. 바로 첫글자가 대문자라는 것이다. 에이~ 그게 뭐 대수라고...하는 이가 있을지 모르지만 여지껏 우리는 어떻게 배워왔나? 클래스는 첫글자를 알아보기 쉽게 대문자로 쓰자고 하지 않았나? 그렇다. System도 클래스인 것이다. 서로간에 규칙을 정하고 이렇게 지켜주면 코드만 봐도 감(?)이 딱 오는 것이다. 그럼 out은? println은? 속사포로 너무 질문하였나? 이걸 한꺼번에 풀어서 설명해 보겠다. System 클래스가 있는데 이 클래스 안에서 하는 일이 여러가지 있지만 그 중에 하나가 out이라는 객체를 이용해서 println() 메소드를 불러다가 괄호안에 있는 입력값을 화면에 출력하는 일이다. 괄호()안에는 " " 따옴표 사이에 출력하고 싶은 문자를 쓰면 된다. 이해가 팍팍 가나? 이미 실행해 보라고 했으니 이미 어느 정도 파악하고 있어야 정상이다. 아니라면 농땡이 피고 있었다는 것이니 자기 머리에 자진 꿀밤 한대씩 주고 반성하도록 하자.

System에 관련된 비밀이 또 하나 있다. 무엇인지 아는가? 이거 파악한 이가 있다면 필자가 바로 쇼크를 먹을텐데... 바로 System이라는 클래스가 어디에 있느냐는 것이다. 불러서 쓰는건 좋다 이거다. 그런데 자바소스 어디에도 System 이라는 클래스를 볼수가 없는데 어떻게 쓴단 말인가? 실행을 해보았으면 알것이다. System 클래스가 없는데도 작동하고 있는 이 놀라운 사실을 말이다. System이라는 클래스는 java.lang.System 이라는 경로에 위치하고 있다. 자바에서는 많이 쓰이는 패키지들을 편리하게 이용하라고 모아놓았는데 그것을 자바 Java API(Application Programming Interface)라고 부르며 그 안에 여러 분류별로 경로가 나누어지는데 가장 기본적으로 많이 쓰이는 것이 java.lang이라는 패키지이다. 이 패키지안에 System 클래스를 비롯 여러 클래스가 들어있다. 예를 들어, 지금 사용하고 있는 System이라는 클래스를 쓰려면 코드 맨위에다가

import java.lang.System;

또는

import java.lang.*;

이런 식으로 표기해 놓아야 해당 패키지 안에 있는 클래스를 이용할수가 있다.(*은 전부를 의미한다. 한마디로 java.lang이라는 경로 안에 있는 클래스 전부를 의미한다.) 자바 소스를 보다보면 import라고 쓰여진 것을 본 이가 있을지도 모르겠다. 바로 이런 용도로 쓰인 것인데 "import 수입하다" 라는 뜻을 가지고 있는 것을 안다면 아마 금방 이해가 갔으리라 생각한다. import는 컴퓨터 용어로는 다른 프로그램에서 데이터를 불러오다라는 의미로도 쓰인다. 이제 됐나? 어허~ 됐다고 하면 안돼지. 왜? 우리의 자바 소스를 다시 한번 보자. 이런 구문이 어디 있는지? 없지? 이상하지? ㅎㅎ 바로 그거다. 이런 구문이 맨 윗줄에 있어야 쓸수가 있는데 이게 없는데도 쓸수 있단 말이다. 왜냐고? 화면을 출력하고 그밖에 숫자나 문자를 다루는 언어요소인데 이런건 거의 모든 자바파일 만들때마다 쓸수 밖에 없다. 그럼 매번 import java.lang 어쩌고 매번 쳐야하는 수고를 해야한다. 이런 수고(?)를 덜어주고자 자바에서는 이 패키지를 기본적으로 로딩한다. 따라서 이 안에 있는 내용은 import 한걸로 가정하고 쓸수가 있는 것이다.

많이 이해가 됐으리라 믿는다. 그럼 print와 println의 차이는? 프로그램을 실행해보고 코드보고 다시 결과보고 코드보고 하다보면 저절로 이해되게끔 소스에 심혈(?)을 기울여 만들어 놓았다. 따옴표 사이에 빈칸이 있는 것은 빈칸으로 읽어드리라고 그렇게 만들어 놓은 것이니 똑같이 있는 그대로 입력해서 실행해 보도록 하자. 해보면 왜 이렇게 빈칸까지 만들어 놓았는지 필자의 깊은 혜안(?)에 감탄을 금치 못할 것이다.ㅎㅎ 실행해 보면 아래와 같은 결과를 얻게 된다.

나는 클래스 Test1의 메인 메소드야.

모든걸 총괄하는 곳이지.

모두들~ 방가 방가^^

에러가 혹시 나는 이들이 있을지도 모르겠다. 자바파일 이름을 잘못 만들었던지 아니면 코드를 잘못쳤던지 그것도 아니면 보통 초보자들이 많이 범하는 대표적인 실수(?)일 것이다. 명령어 라인 끝에다가 ;(세미콜론)을 붙여야 된다는 것을 잊지 않았는지 다시 한번 확인하자. 그리고 설마 실행하는 방법을 까먹은 이들은 없겠지? 있다면 저번 강좌를 찾아보도록 한다. 자바 에디터를 쓰고 있다면 버튼 하나 눌리면 될텐데 그거 하나 못찾는다면 정말 평생 고생이다. 잘좀 하자. 이 예제에서는 끊어진 문장들이 하나로 연결될수 있음을 소스를 통해 보여주고 있다. print라는 메소드를 이용하면 출력이 끝난 그 자리에서 계속적으로 다음 메세지를 기다리는 것이고 println이라는 메소드를 이용하면 출력을 끝내고 다음줄로 가서 그 다음 메세지를 기다리게 됨으로 위와 같은 결과가 나오게 된다. 저번에 많은 내용을 공부하였으니 오늘은 이 정도로 강좌를 마친다. 너무 짧다고? 묻지도 말고 따지지도 말고 쉬어라. 언제 또 이렇게 쉬겠나? ㅎㅎ

혹시나 이해가 가지 않는 부분이 있으면 중간에 졸았다거나 뭔가 먹으면서 딴짓했던가 그럴 것이다. 반성하고 다시 읽어서 자기것으로 만들도록 하자. 특히 저번 강좌에서 다룬 메인메소드에 관한 내용은 그냥 넘어가도 안될건 없지만 확실하게 잡아놓으면 상당히 많은 시간과 노력을 절약하게 될것이니 이번 강좌를 통해서 자바를 처음으로 시작한 이들은 꼭 다시한번 읽어보길 추천한다. 이제 여러분은 위의 예제를 통해서 원하는 문자들을 화면에 마음껏 출력할수 있는 능력(?)을 가지게 되었다. 어렵게 얻은 소중한 능력을 다음에 만날때까지 마구마구 응용해 써보기 바란다.^^

2011년 4월 20일 수요일

자바의 메인메소드(Main Method)

자바 프로그램은 클래스와 메소드의 집합체라고 해도 과언이 아니다.
일단 클래스와 메소드를 자바코드로 쓰는 방법을 살펴보자.

class Robot
{
??????????; //이 공간에다가
?????????; //변수를 선언하고 초기화한다.
????????; //이 공간을 필드(fields)라고 부른다.

void method( ) //메소드를 만드는 형식이다.
{
???????; // 역시 클래스처럼
???????; // 중괄호라고 하나? 그거 오픈하고
???????; // 이렇게 몇줄이든 내용을 쓰고
???????; // 아래처럼괄호를 닫으면 된다
???????; // 달려라 달려 로보트야~
} //method 메소드 끝내기

} //Robot 클래스 괄호닫기

클래스와 메소드는 내용의 시작과 끝을 중괄호 기호인 {와 }를 통해 알수 있으며 자바 프로그램은 소스를 읽어들일때 빈칸이나 빈줄은 무시하고 명령어들을 읽어드린다. // 슬래시를 치고 쓰는 내용은 자바에서 읽어드리지 않는다. 여기다 쓰는 내용을 주석이라고 하는데 프로그램에 대한 설명이나 중요한 사항을 메모하는 용도로 사용한다. 프로그램이 길어질때 어떤 클래스나 메소드 괄호인지 찾기 힘들때가 있는데 그럴때 이런식으로 표기해두면 편하다. 그리고 클래스와 메소드 사이에 빈칸이나 빈줄은 자기 마음대로 쓸수 있으나 프로그램의 내용과 구문을 금방 파악하기 위해 괄호의 열고 닫는 위치를 같게 만들고 클래스나 메소드 구문에 관련된 라인을 처음 입력할 때에는 한줄씩 띄우는게 보기 편하다. 지금 위의 코드에서 method라는건 명령어가 아니라 한번 생각해 보라고 메소드 이름 자체를 method라고 써놓은 것이다. 즉 아무 이름이나 쓰고 싶은데로 쓸수 있다. 평소에 자바에서 메소드라는 표현을 쓸때는 "결과값 ???(입력값)" 이 라인 전체를 의미하는 것이다. 이제 명령어 자체가 method라고 착각하는 이는 이 시간 이후로 없길 바란다.

그럼 void는 무엇인가? 자, 사전을 찾아봤다고 가정하고 "void 빈공간,텅빈" 뭐 이런 뜻이 있는데 여기서도 마찬가지로 생각하면 된다. 저번에 필자가 메소드의 형식은 어떻게 쓰는지 말했는데 기억하는가? 모르면 앞에꺼 찾아보자. 결과값이라고 했는데 이제 생각나는가? 안난다면 자기 머리에 꿀밤 한대씩 주고 다시 시작하자. 그렇다. 결과값이다. 그럼 뜻이 비어있으니 뭐겠는가? 결과값을 받지 않겠다는 소리다. 지금 여기서 쓰인 void는 결과값이 없는 메소드다. 무슨 행동을 시켜놓고 결과가 필요없다? 여기서 결과값이란 메소드로 실행하고 나서 다시 그 값이 글자(String)든 정수(int)든 값을 받아서 뭔가 다시 할 필요가 없다는 뜻이다. 그럼 메소드 이름 옆에 괄호안은 뭐였었나? 기억나나? 아까 볼때 못봤나? 머리 안돌아가면 몸이라도 부지런해야한다. 빨리 다시 찾아보자. 그렇다. 입력값이다. 그런데 괄호안이 비었다. 아무것도 없으니 입력값도 없다는 소리다. 즉, 아무 입력값을 받지 않더라도 메소드를 부르면 자동적으로 뭔가를 하라고 지시하는 것이다. 반대로 입력값이 있으면 메소드를 행하기 전에 입력값이 올바른지 점검해보고 계속 진행할지 안할지를 결정할수 있는 메소드를 만들수도 있고 입력값으로 덧셈이나 뺄셈같은 계산을 할수도 있고 암튼 입력값이 있으면 쓰이는 용도가 더 다양해진다고 볼수 있겠다.

public class Test1
{
public static void main(String[ ] args)
{
System.out.println("");
System.out.print("나는 클래스 Te");
System.out.print("st1의 메인 ");
System.out.println("메소드야.");
System.out.println(" ");
System.out.print("모든걸 총괄하는");
System.out.println(" 곳이지.");
System.out.println( );
System.out.println("모두들~ 방가 방가^^ ");
}
}

자 어떤가? 이제 프로그램이 눈에 들어오기 시작하남? 지금 이 예제는 Test1이라는 이름의 클래스 한개와 main이라는 이름의 메소드 한개를 가지고 있는 자바 프로그램이다. 메소드 안에 내용을 보면 뭔지는 모르겠지만 print 어쩌구 저쩌구 하는거 보니 뭔가를 쓰라고 하는 명령어라고 짐작할수 있을 것이다. 더군다나 출력하는 문장을 한글로 써놨는데 이거 감 안오면 정말 난감하다.^^ print라는 뜻은 다 알테니 말그대로 그뜻이고 그렇다면 println은 뭔지 궁금할 것이다. println은 문장을 찍고 엔터를 친 상태 즉 출력후 다음줄에 가서 다음 명령을 대기하라는 소리다. 그럴듯(?)하게 쓸려니 힘들구나. ㅎㅎ 이제 따옴표가 괄호안에 있는게 보일텐데 글자를 출력하려고 할때는 저렇게 괄호 양옆에 따옴표를 쓰고 그 사이에다가 원하는 글자를 입력해야 출력이 된다. 그리고 글자 출력하라는 명령어 끝을 보면 뭔가가 있다. 뭐? 세미콜론(;), 필자가 말하기 전에 신경쓰고 있는 이가 있었을지 모르겠다. 모든 명령의 끝에는 저렇게 ;을 붙여야한다. 그래야 자바 프로그램이 한 라인의 명령어가 끝났구나라면서 알아먹는다. 아까 맨처음 위에서도 세미콜론이 물음표 옆에 있었는데 혹시 누군가가 세미콜론을 왜 썼지라면서 의아해 했다면 그대가 자바 천재(?)임을 필자가 인정하겠다.^^


저번 시간에 이어서 설명할 부분은 바로 메인 메소드다.
public static void main(String[ ] args)
{
명령1;
명령2;
명령3;
.... ;
}

메인메소드의 정의는 프로그램을 실행했을때 자바에서 가장 먼저 읽어들여서 명령들을 다 작동하고 그것이 끝나면 프로그램을 종료하는 공간이 바로 메인메소드이다. 그런 까닭에 결과값은 항상 없다. 프로그램이 끝나는데 결과값을 받아서 또 써먹을때가 없다. 프로그램을 끝내야 하니까 메인메소드는 항상 void이다. 더불어 메인메소드의 이름도 말 그대로 항상 main으로 이름지어야 한다. 왜? 메인메소드이니까...(이렇게 설명하면 몰매 맞겠군.^^*) 그건 자바에서 처음 시작하는 메인메소드의 이름은 반드시 main으로 하라고 자바소스를 읽고 작동시키는 머신 일명, JVM이라고 불리우는 자바가상머신에게 그렇게 입력(?)해 놓았다. 그래서 선택의 여지가 없다. 프로그램을 작동시키려면 main이라는 이름의 메인메소드를 쓸수밖에 없는 것이다.

그럼 안에 입력값이라고 쓰여있는 String[ ] args 는 무엇인가? 일단 String(스트링)은 여러가지 뜻이 있는데 여기선 악기의 "줄"이라는 그런 뜻이 아니고 컴퓨팅에서는 "문자열"이라는 뜻으로 쓰인다. 어쩌다가 이 세계에서 그런 뜻으로 쓰였는지 아는 이 있으면 알려주기 바란다.^^ 그렇다면 [ ] 는 무엇인가? 문자열이 여러개 있다는 뜻인데 이것을 우리는 배열(Array)이라고 한다. 그럼 일단 문자열은 무엇인가? 문자를 한개부터 일렬로 세운거다. 예를 들어, 문자 하나는 "비", 문자 두개는 "Ya", 문자 세개는 "그만혀" 그렇다면 문자열 배열은? {비, Ya, 그만혀} 뭐 이런식으로 모아놓은 것이지 않을까? ㅎㅎㅎ 이런 문자열을 지칭할때 String[ ] 을 쓰고 그 문자열을 지칭하는 이름이 args인 것이다. 솔직히 이름이므로 args 이거는 아무거나 써도 되나 인수 혹은 매개변수라는 뜻의 arguments 약자로 쓰인 것이니 특별한 일이 없는한 바꿀 필요는 없다 하겠다. 한국말이 어렵다. 매개변수는 뭐냐? 이렇게 직설적으로 물으면 대부분 대답하기가 힘들 것이다. 그냥 막연히 무슨 값을 얘기할때 그렇게 쓴다 정도로 이해할텐데 자세히 풀자면 프로그래밍에서 함수(메소드)나 프로시저(메소드 비슷한거..영어다..사전 찾아보자)를 호출할 때 호출하는 쪽에서 실제로 넘겨주는 값을 얘기할때 매개변수라 한다. 뭔가 하나를 알려고 하면 이렇게 끝이 없는 것이다. 음 철학적이군..-

문자열 배열이 왜 필요할까? 지금 위에서 본 문자열 배열중에 세번째 스트링인 "그만혀"만 어디다가 가져와서 쓰고 싶다. 그러면 args[2] 이런식으로 명령해서 불러쓴다. 첫번째 스트링이 필요하면 args[0] 이런식으로 표기해서 불러쓰기 쉽도록 만들어 놓은 것이다. 그리고 방금 눈치빠른 이들만 알아챘겠지만 시작은 0에서 시작한다. 숫자는 0(?)부터 시작하니까 하하~ 왜 1에서 시작하지 0에서 시작했을까? 바로 이것 때문이다. 이 배열에 문자열이 몇개나 있나 물어보면 답이 뭘까? (정말 몰라?) 세개잖어~ 그럼 어떻게 세야되나? 하나 둘 셋...1 2 3...길이를 셀때는 1부터 시작해야 한다. 이해되지? 안되면 큰일이다. 그런데 이렇게 배열을 세어서 알려주는 표기방법이 있다. "이름.length" 여기선 이름이 args 이니까 args.length 로 길이를 물어보는 명령을 넣으면 3이라는 답을 얻을수도 있다. 배열에서는 처음과 끝을 어떻게 알수 있을까는 방금 말한 길이를 통해서 알수 있는데 여기처럼 배열에서 길이를 알면 문자열 세개까지만 검색하고 더이상 시간을 지체할 필요가 없다. 아니면 없는데도 계속 검색하는 바보짓(?)을 하는 경우가 생길테니까 말이다. (물론 자바에서는 없는데 검색하면 null에 관계된 에러가 날것이다. 역쉬~ 자바!)

그럼 메인메소드 안에 배열은 왜 쓴거야? 이렇게 의문을 품은 이들은 아 착하다. 뭐 좀 먹고 와라. 다시 메인메소드의 정의를 살펴보자. 가장 먼저 읽어들인다는데 어디서 먼저 읽어드릴까? 바로 "명령프롬프트"창에서다 기억나는가? 시작할때 java Test1 이라고 입력해야 된다고 했던것을~ 여기 문자열을 읽을 필요가 있을때를 대비해서 고맙게도 자바는 이렇게 문자열 배열을 만들어 놓은 것인데 이해가 쉽도록 시작 명령어를 설명과 함께 다시 써보겠다.

java Test1 args[0] args[1] args[2]......

즉, 여러분이 처음 자바소스를 실행할때 파일이름 옆에다가 어떤 문자열을 파일이름 옆에 입력해 놓을수도 있는데 자바에서 이것을 스트링 배열의 요소인 args로 읽어다가 프로그램에 써먹을수가 있다. 그러나 평상시에 프로그램 시작시킬때 특별히 전달할게 없으므로 아무것도 쓰지 않으니 입력값을 넣는 메인메소드의 괄호안은 보통 비어있는 것이나 마찬가지라고 생각하면 된다. 지금은 처음이라 필요가 없겠지만 여러분들이 진정한 자바 프로그래머로 탄생(?)하게 될 역사적인 순간에 이런걸 써먹을수 있도록 자바신(?)께서 메인메소드를 통해 이미 준비해 놓으셨다는 사실을 상기만 하고 지금은 이해할 필요도 없고 다른거 공부해야되니 후딱 머리 비우기 바란다.^^

public은 저번에 설명해서 알겠고 static이 무엇인지 궁금한 이가 많을 것이다. 흔히 메소드 앞에 static을 붙이면 정적메소드라고 하는데 이 부분 때문에 자바를 웬만큼 하는 이들도 이 부분 특히 메인메소드의 static만 나오면 자신이 없어지는 이가 많은데 일단 사전적인 의미는 "static 고정된, 움직이지 않는" dynamic의 반대말이다. 다이내믹이 뭔가 역동적인데 반해 뭐 가만히 있어도 된다는 그런 뜻인가? 헐~ 바로 그거다. 뭔가를 할 필요가 없다는거다. 가만있어도 알아서 해준다는거다.

오늘의 마지막 이슈 그 이름도 유명하고 많은 이들을 자바 공포로 떨게 하고 있는 static을 통해 오늘의 데미를 장식할까 한다. 자바를 오래 공부한 이들도 상당히 이해하기 어려운 부분에 속하는 것이 메인메소드인데 풀어서 설명은 하겠으나 처음 보는 이들은 자바에 대한 개념(?) 자체가 정립되어 있지 않으므로 필자가 아무리 쉽게 설명하더라도 이해를 못할수 있다. 그럴경우 그냥 메인메소드는 이렇게 써야되는구나 생각하고 무조건 외워서 써라. 먼 훗날 필자의 설명이 가슴속에 자삘(feel?)로 꽂힐때가 있을 것이다.ㅎㅎ

다시 돌아와서... 뭐를 알아서 해주는걸까? 컴파일할때 알아서 클래스를 제약없이 마음껏 불러서 쓸수 있게 만들어 주는 공간이라고 알아두자. 그럼 평상시에 클래스를 쓰고 싶을때 어떻게 해야 쓸수 있는지를 알아야하는데 new 라는 키워드를 통해 클래스를 재정의해서 쓰게 되며 우리는 이를 "객체" 혹은 "인스턴스"라고 부른다.

그럼 여기서 우리가 위의 메인메소드에서 맨위의 Robot 클래스안에 있는 void method( )라는 메소드를 불러서 쓴다고 가정하자. 결과값은 넣어봐야 아는 것이니까 그걸 빼고 명령을 주는데 그러면 그냥 method( )를 치면 동작해야 하는데 작동하지 않는다. 자바에서는 클래스를 이용한 객체 생성을 통해서 메소드에 접근할수 있도록 만들어 놓았기 때문이다. 바로 이렇게 말이다.

Robot x = new Robot( );

바로 로봇 클래스를 이용한 객체 생성을 완료하였다. 유식한 말로 인스턴스화했다고도 한다. 여하튼 이 인스턴스의 이름은 x이다. 이제 메소드를 부를수가 있다. 뭐를 통해서? x라는 인스턴스를 통해서 이런 식으로 사용한다.

x.method( );

이런 식으로 다른 곳에 있는 메소드를 불러서 쓸수가 있다. 조금 공식화해서 보여주자면,

인스턴스 생성시는~

클래스 인스턴스이름 = new 클래스( );

인스턴스 부를때는~

인스턴스이름.메소드이름(입력값);

이렇게 되겠당~

왜 static 하다 말고 이걸 설명하는거야? 라고 묻는이가 있을 것이다. 여기까지 이해를 해야 설명이 가능하기 때문이다. static의 기능이 여러가지 있지만 여기서 이해할 부분만 짚고 넘어가겠다. 필자가 프로그램의 시작과 끝이 메인메소드에서 이루어진다는 것을 못이 박히도록 얘기했는데 기억나겄지? 메인메소드도 엄밀히 이야기하면 클래스안에 있는 것인데 그럼 시작할때 메인메소드도 객체생성을 한후 불러서 쓸수 있어야 하지 않겠는가? 그럼 프로그램 실행할때마다 메인메소드가 안에 들어있는 클래스를 객체 생성하라고 시키고 자바소스를 실행시켜야 할것이다. 이 얼마나 난감한 일인가? 그런데 알다시피 우리는 그냥 자바소스 컴파일한후(이때 자바소스를 읽어들일때 static의 존재여부에 따라서 메인메소드가 어디에 있는지도 찾아내는 것이다)에 객체생성 이런거 없이 그냥 자바 프로그램 실행해서 메인메소드 너무나 당연하다는듯이 작동시키고 있는데 고맙게도 이런 수고(?)를 덜어준 바로 그 황금같은 단어 static이 메인메소드 앞에 딱 붙음으로써 모든 자바 프로그래머들이 그런 번거로운 작업에서 해방되었다는 믿기힘든 전설(?)이 미국 실리콘밸리 어디에선가 전해오고 있다고 한단다.ㅎㅎ

public static void main(String[ ] args)
public static void main(String args[ ])
public static void main(String[ ] apple)
static public void main(String orange[ ])
static public void main(String[ ] tiger)
static public void main(String lion[ ])

메인메소드를 써봤는데 여섯개 중에 뭐가 틀렸을까?
모두다 정답이다. 허걱~ 그럼 강이가 답해설을 하겠다. 두근두근~ ^^
public이랑 static은 위치가 바뀌어도 전혀 상관이 없다.
args는 아까전에도 얘기했듯이 매개변수 이름일뿐 아무거나 써도 된다.
배열을 뜻하는 [ ]은 변수 앞이나 뒤나 어디에 위치해도 상관없다.
너무나 당연하지만 void main( )는 순서 절대 바뀌면 안된다.
이유는 메인메소드이니까 메소드 형식에 따라 "결과값 이름(입력값)"의 형식을 취한다.
여기서 필자가 추천하는 메인메소드 형식은 첫번째 구문이다.
public static void main(String[ ] args)
모든 명령어 의미 하나하나가 순서대로 빠르게 전달될뿐 아니라 깨끗하고 명료하니 여러분도 이렇게 쓰는데 익숙해지기 바란다.
더불어 메인메소드는 위와같이 항상 똑같은 형식이니 이번 기회에 그냥 외워버리자.

메인메소드 하나 가지고 이렇게 많은 내용을 일일히 설명하는게 어이없게 보일지도 모르겠으나 그 노력은 헛되지 않을 것이며 여기까지 소화하며 따라온 이들에게 필자는 경의를 표하고 싶다. 다시 강조(?)하지만 메인메소드 하나 가지고 울어먹은것 절대 아니다. 믿어달라.^^ 자바를 웬만큼 하는 이들도 메인메소드를 이 정도까지 독파하고 있는 이들은 상당히 드물 것이다. 여러분이 처음 자바를 시작했더라도 오늘 설명한 강좌를 확실하게 이해했다면 어느 누구에게도 웬만해서는 꿀리지 않는 자바 프로그래머의 첫 단추를 제대로 끼웠으리라 확신하면서 오늘은 여기서 끝내겠다. 수고 많았다. 쉬어라~ ㅎㅎ

2011년 4월 19일 화요일

자바의 기본문법(Structure)


예고편(?)을 본 이들은 이미 알겠지만 그래도 시작하려니 머리가 지끈지끈 아플 것인데 특히 위의 프로그램이 엄청나게 어려운 자바 소스(?)니까 말이다. 하지만 필자를 믿고 따라오면 과반수 이상, 아니 절반, 아니 반의반 정도는 이해하고 고개를 끄덕거리는 뛰어난 천재(?)가 있기를 기대하면서 본격적인 강의를 시작해볼까 한다.

여러분은 이미 자바의 모든 것을 갖추었다. 자바소스만 빼고 말이다. 그렇다면 설치된 자바 에디터를 열고 새로 시작하기 버튼 눌러 파일이름을 맨 첫째줄과 같이 Test1.java 라고 만든다. 그리고 위와 똑같이 자바 코드를 프로그램에 입력하라. 묻지도 따지지도 말고 똑같이 말이다.(잘 안보이면 마우스로 그림을 클릭~) 여기서는 코드를 그냥 쓰면 잘 안보이는 관계로 울며 겨자먹기로 그냥 타이핑해야 되지만 행여 다른 곳에서라도 코드를 마우스로 복사해서 붙여넣기하는 잔머리 뛰어난 인간들이 있을지 모르겠으나 프로그래밍 할때 타이핑 하는 시간을 아끼지 말아라. 프로그래머는 자고로 시간을 아끼지 말고 철저히 시간을 낭비(?)해야 발전할수 있는 이상한 곳이니까 말이다. 희한하게 자기가 시간을 들이고 직접 쳐봐야 자기 것이 된다. 이것이 프로그래머들이 공공연하게 가르쳐주지 않는 최고의 비밀(?)이 아닐까 생각한다.

자 다 입력했다면 프로그램을 실행시켜보자. 명령 프롬프트창을 열고 자바파일이 있는 디렉토리안에서 아래와 같이 순서대로 입력한다.

javac Test1.java
java Test1

첫째줄은 컴파일하라는 뜻이고 한마디로 자바소스를 읽어서 실행할수 있는 형태의 파일(.class)을 만들라는 것이고 둘째줄은 그 파일을 실행하라는 뜻이다. 실행할때는 확장자를 빼고 써야됨을 절대 잊지 말자. 참고로, 자바 에디터를 써서 입력했다면 파일이름(만드는 원리를 저번시간에 설명했는데 기억을 하고 있는지 원..-)을 만들어서 저장하고 Run 이나 Compile이라는 명령어를 찾아 마우스를 클릭한다. 플레이 버튼의 아이콘이 자바 에디터에선 보통 이런 명령어다. 프로그램을 실행해보면 글자가 화면에 출력될 것이다. 자바소스와 출력된 화면에 글자들이 어떻게 찍히는지 살펴보도록 하고 디렉토리안에 어떤 파일들이 생기는지 또한 찾아보기 바란다.

아까 여러분이 코드를 치면서 한가지를 느꼈을 것이다. 자바 파일이름과 public class 옆에 있는 이름이 파일확장자만 빼면 같다는 것을 말이다. 자 굉장히 중요한 개념을 설명하려한다. 묻지도 따지지도 말고 무조건 외워라. 복창한다. public class 옆의 이름은 자바의 파일이름과 토시 하나 틀리지 않게 똑같이 만든다. 그래야 작동한다는 전설(?)이 자바 왕국에 있다. 이게 바로 그 유명한 자바 파일이름 만들기의 핵심원리다. 자기 마음대로 아무 이름이나 자바파일에 갖다붙여서 쓰는 황당한 이(?)들이 앞으론 없길 바라면서 계속 진행한다.

쳐보니 또 한가지 느끼는게 있을 것이다. 생각보다 길다고? 앞으로 더 긴 코드가 무궁무진하니 이걸로 겁먹지 말자. 일단 자바를 잘하기 위해서는 영어(?) 공부를 무쟈게 열심히 해야한다. 왜? 자바 코드를 한글로 쓰나? 당근 영어로 쓰지. 그래서 영어를 무지 잘해야 한다. ^^ 오늘 필자는 자바보다는 영어에 초점을 맞출 것이다. 일단 영어를 알면 자바는 저절로 풀린다. 믿거나 말거나~

class
public
static
void
main
String
System
out
print
println

일단 위의 소스에서 핵심키워드를 간추려 보았다. 뜻은 모두 사전을 찾아보기 바란다. 필자가 뜻을 다 쓸까 하다가 공부는 스스로 하는거니까 안쓰기로 특별히 결단(?)을 내렸다. 빨리 찾아보자. 일단 자바 프로그램은 어떻게 구성되어 있는지 큰 그림을 알아야 눈에 들어오기 시작한다. 뭐든지 공부할때 개요를 파악하고 전체의 흐름을 알면 공부하기 쉬워진다. 부분적으로 알고 파고 들다보면 자신이 뭐 공부하고 있는지 놓칠때가 많다. 그런 우를 범하지 않기 위해 먼저 자바의 큰 그림을 대충 이해해 보도록 하자.

자바는 크게 "패키지(package)"와 "클래스(class)"와 "메소드(method)"로 구성되어 있다. 다른 말로 열라 어렵게 설명하자면 메소드가 모여서 클래스를 이루고 클래스가 모여서 패키지를 이루고 패키지가 모여서 거대한 자바 프로그램이 완성된다. 좀 멋드러지게 표현할려 했더니 어색하지만 이제 서서히 자바 프로그램의 윤곽이 잡히지 않는가? 안잡혀? 그럼 다시 한번 읽어보고 본인이 쳐넣은 자바 소스를 다시 한번 읽어본다. 읽어봐도 잘 모르겠다면 이런 질문을 하고 있을지 모르겠다. class만 보이고 다른건 안보이는데... 호오~ 대단하다. 사실 처음이라 복잡한 프로그램을 만들 일이 없으니 패키지는 웬만해서는 초반에 보기 힘들다. 그럼 메소드는? 물론 있다. 그것도 딱 하나~ 말 나온김에 커다란 비밀(?)을 얘기하자면 모든 자바 프로그램은 최소 한개 이상의 클래스가 있어야 하고 또한 최소 한개 이상의 메소드가 있어야 한다. 그런데도 메소드는 희한하게 보이지 않을 것이다. 왜? 아직 안배웠으니까...ㅎㅎ 힌트를 주자면 메소드는 언제나 클래스 안에 위치한다. 이제 서서히 메소드가 이거 아닌가하는 감이 잡히나 아직도 모를 것이다. 왜? 메소드는 클래스처럼 명령어 이름이 method가 아니고 형식 자체를 메소드라 부르는 것이기 때문이다. 그럼 어떤 형식으로 클래스랑 메소드가 만들어지는지 살펴보자.

public 클래스의 형식:   public class 파일이름
(public이 붙을 경우는 파일이름과 꼭 같아야함을 잊지말자!)

클래스의 형식:   class 이름
메소드의 형식:   결과값 메소드이름(입력값)

예제를 곁들여 설명하자면 Test1 자바 소스에서는

public 클래스의 형식:   public class Test1
클래스의 형식:   public만 빼면 위에꺼랑 같다. 당연한가?
메소드의 형식:   void main(String[ ] args)

자바 파일에 최소한 하나의 (public) class는 존재해야 된다. 그래야 파일이름을 만들수 있으니까 말이다. 이게 클래스의 존재이유라고나 할까나? 그리고 public이 붙을 경우엔 그 클래스의 이름이 파일이름과 똑같아야 한다. 다시 말하면, 여러개의 클래스는 만들수 있으나 public class는 개별 클래스 중에선 단 하나의 클래스에서 밖에 사용할수 없다. 개별 클래스는 무슨 말인가? 클래스를 말그대로 따로따로 만든걸 의미한다. 클래스안에 메소드만 만들수 있는건 아니다. 성격이 다르다고 판단될 경우 프로그래머의 역량(?)에 따라 클래스안에 또 클래스를 만들수 있다. 자바를 많이 한 이들조차 상당히 헤깔려하는 부분이나 여러분은 확실히 잡길 바란다.

대부분의 경우 메인명령을 실행하는 메인 메소드가 있는 클래스에 public이란 이름을 붙이는게 관례인데 프로그래밍 하다보면 저절로 그렇게 될 것이다. 그럼 public은 무엇인가? 자, 아까 찾아본 단어의 뜻을 생각해본다. 기억 안난다고? 후딱 다시 찾아보자. "public 공공의, 공개되는" 뭐 이런 뜻이 나온다. 그렇다. 바로 그런 뜻으로 쓰인 것이다. public을 지정한 클래스 내용물은 공개되어 있어 안에서든 바깥에서든 누구나 쓸수 있다.

여러분이 프로그램을 짜야한다면 그것은 어떤 목적을 가지고 있을 것이다. Test1이란 자바 파일은 글씨를 화면에 출력하는게 목적이다. 따라서 그 목적을 이루기 위한 제목을 생각해서 적절하게 이름을 짠다면 Test1 이란 이름보다는 Print 라는 이름이 적합했을 것이나 필자를 비난하지 말고 마음에 들지 않으면 바꾸도록 하자. 클래스 이름을 바꿨다면 뭘 또 해야되나? 설마 벌써 까먹은건 아니겠지? 글치, 파일이름도 Print.java 로 바꾸어야 할것이다. 보통 클래스 이름의 첫글자는 메소드와 구별을 쉽게 하기 위하여 대문자로 쓴다.

그 다음은 글씨를 직접적으로 화면에 쓰라는 명령과 방법(method)을 제시해 주어야한다. 그 명령들이 있는 곳이 바로 메소드(method)라고 불리는 공간이다. 위의 프로그램은 바로 메소드의 이름이 main 이다. 이것이 자바에서 처음 프로그램을 실행하도록 만들어주는 그 이름도 유명한 메인 메소드란 것이다. 메인 메소드도 public class 처럼 개별 클래스 중에서 단 한군데만 존재한다. 프로그램의 처음이자 마지막이라고나 할까? 더불어 쓰는 방법도 메인 메소드는 독특한데 시작과 끝이라 public static void main(String[ ] args) 의 형태로 항상 똑같이 쓰인다. 그냥 외워도 무방하나 모든 명령을 총괄하는 프로그램의 핵이라고 할수 있는 메인 메소드는 글이 생각보다 길어지는 관계로 다음에 살펴보기로 하자. 쉽게 설명하려고 하다보니 자바 강좌가 아니라 소설 같다. 제목을 장편 대서사시 "소설 JAVA"라고 고치는거 신중(?)하게 생각해봐야겠다. 소설 잡아? ㅎㅎ

2011년 4월 18일 월요일

자바 설정 및 실행(Java Setting & Execution)

저번 시간에 자바를 설치하였다면 오늘은 자바를 편하게 쓰도록 설정을 해보죠. "시작->모든 프로그램->보조 프로그램->명령 프롬프트" 라는 창이 있는데 그걸 오픈하세요. 그리고 자바의 컴파일 명령어인 javac 를 쳐보세요. 다음에 컴파일된 자바를 실행시켜주는 명령어인 java 도 치고 엔터 눌러보세요. 둘 다 잘 되나요? 헉, 혹시 안되나요? 놀라지 마세요. 파일 못찾겠다고 안돼야 정상입니다. ^^

우리가 필요한 실행파일은 javac.exe 랑 java.exe 입니다. 자바로 프로그래밍할때 우리가 만든 소스를 작동시킬수 있는 형태로 변환(컴파일) 시켜주는 javac 와 그 변환된 프로그램을 실행시켜주는 java 파일이 필요한데 그 파일들은 여기에 있습니다. 지금 쓰는 디렉토리명은 버젼에 따라 조금 다를수 있겠지만 "C:\Program files\Java\jdk1.6.0_23\bin" 디렉토리안에 들어 있습니다. 이 안에서 소스를 만들고 프로그램 실행시키고 할수도 있겠지만 그러면 원래 있는 파일들과 섞여버려서 난잡하겠죠? 그래서 어디서나 실행할수 있도록 설정을 고쳐주는게 좋습니다. 방법은 아래와 같습니다.

먼저 여러분의 바탕화면에서 "윈도우즈 버튼+Pause Break 버튼"을 누르시면 "시스템 등록정보"가 나옵니다. 마우스를 좋아하시면 "내 컴퓨터"에서 오른쪽 마우스 버튼 누르시고 "속성"을 선택하셔도 나오구요. 거기서 "고급" 탭을 누른후에 보시면 "환경변수"가 있습니다.


들어가시면 밑에 "시스템 변수" 란이 있죠? 거기 창에 보시면 "Path"라는 라인이 있을 겁니다. 거기에 마우스 지정하시고 아래 "편집" 버튼을 누르세요.


그리고 "변수값" 이라고 되어 있는 곳의 끝에다 ;C:\Program Files\Java\jdk1.6.0_23\bin 이런식으로 붙여주고 다 확인 버튼 누르시고 나오시면 됩니다. 앞에 세미콜론이 있어야 앞의 라인과 구별이 되야하니 꼭 붙여주시기 바랍니다. 이미 세미콜론이 쓰여있다면 당연히 붙일 필요없구요.


그리고 기분 전환 삼아 가볍게 컴퓨터를 리붓하고 다시 시작해 봅시다. ("시작->모든 프로그램->보조 프로그램->Windows 탐색기"를 이용해서 자바 bin 디렉토리로 가시면 주소창에서 디렉토리 경로를 편하게 복사하실수 있습니다.)



이제 아까 얘기한 "명령 프롬프트"창을 오픈하고 javac 나 java 를 입력해 보세요. 뭐라고 뭐라고 하면서 작동하죠? 이젠 어디서나 여러분이 자바로 짠 프로그램 소스를 컴파일하고 실행시킬수 있는 자바 프로그램 설정이 모두 완료된 것입니다. 자바 소스는 파일명이 *.java 이고 그 소스를 실행할수 있게 만든 즉 컴파일이라고 표현하는데 컴파일된 파일명은 *.class 라고 합니다. 즉 .class 를 만들기전 컴파일 하기전에 여러분이 .java 소스를 프로그래밍해야 하는데 시중에 편하게 여러분이 코딩할수 있는 에디터 프로그램이 많이 나와 있습니다. 그런데 사실 이 소스들은 텍스트 형식이기 때문에 윈도우즈에 있는 메모장으로도 얼마든지 여러분이 프로그램을 짤 수 있습니다. 일단 처음이니 기본으로 깔려있는 메모장으로 짜보시고 차차 여러분이 원하시는 자바 에디터를 골라서 사용해 보시기 바랍니다. 이번에는 여기까지 하고 인터넷에서 파일명이 *.java로 되어있는 파일들 다운받아서 안의 내용을 메모장으로 한번 열어보세요. 내용은 몰라도 어떤 프로그램인지 이제 여러분도 실행해 볼수 있습니다. 실행은 명령 프롬프트창 여시고 자바 파일이 있는 디렉토리에서

javac 파일이름.java

이렇게 하면 컴파일이 되면서 파일이름.class 가 생성이 됩니다.
그런후에 이 생성된 파일을 실행시키면 프로그램이 작동됩니다.

java 파일이름

여기서 실행할때 확장자인 .class 는 생략되니 잊어버리지 마세요.

위의 두가지 명령은 자바 공부하는동안 지겹도록 쓰게 됩니다. 자바 에디터를 사용하게 되면 물론 여기서 해방입니다. 버튼만 눌리면 이런 명령어들을 알아서 실행해주니 편하고 기본 명령어들을 색깔로 표시해줘서 코드 보기도 수월합니다. 메모장은 글씨가 흑백이니까요. 그런 점 때문에 자바 에디터를 보편적으로 많이 사용하고 있으니 필요하신 분들은 아무 자바 에디터나 설치하고 다음부터 그 에디터로 같이 따라해보시면 됩니다. 못구하셨으면 불편하시더라도 그냥 메모장 쓰셔야죠. ㅎㅎ

예고편: 이렇게 어려운 코드(?)를 다음에 짤 예정임. 긴장바람. 두근두근 ^^*

처음부터 자바 에디터 없다고 포기하시는 분(?)이 나올 가능성이 있을지도 모르겠군요. 그럼 너무 불공평한가?? 마음에 드는거 못구하셨으면 Xinox Software사에서 나온 JCreator LE 5.00 무료버젼을 한번 써보시기 바랍니다.


용량이 작으면서도 깔끔하고 다양한 기능을 제공하는 자바 에디터입니다. 진작 자바 에디터 설치하는거 가르쳐주지 명령프롬프트창 열고 힘들게 자바 실행하는 방법을 왜 갈켜줬냐고 하시는 분이 있을지 모르지만 에디터가 만병통치약은 아닙니다. 하다보면 아시겠지만 컴파일은 되는데 실행이 되지 않을때가 있습니다. 그럴 경우에는 오리지날 자바 프로그램을 직접 돌려 컴파일하고 실행하면 되니 기본을 게을리하지 말아주세용~~ 별꺼 아닌 내용인데도 굉장히 글이 길어지네요. 다음부터는 타이핑 횟수(?)도 줄일겸 말 편하게 할테니 이해하셈~ ^^

자바의 작동원리를 설명한 개요도인데 다음시간에 본 내용에 들어가기에 앞서 감상(?)부터 하시기 바랍니다. 우리는 바로 첫번째 Java Source Code를 만드는 것이 주요한 임무가 될것입니다. 그것이 자바 프로그래머의 역활이고 나머지는 자바 프로그램이 다 알아서 해줄 것이니 염려 푹 놓으시기 바랍니다.^^