본문 바로가기
국비수업

[국비 Java 7일차] for문 뽀개기 구구절절 설명충

by 박다비 2022. 10. 26.

 

오늘은 5시에 집에와서 씻고 밥먹고 청소하고 7시에 컴터앞에 앉기 성공!

근데 앉아서 8시까지 깃허브 연동이랑 씨름 하다가 포기하고 돌아옴...

 

내 깃허브 문제는

오늘 수업에서 새로 작업한 클래스의 새로운 내용이 이클립스에 반영이 안된다는 것이다...

깃프로그램에도 제대로 반영됐고 내 컴퓨터의 연동한 폴더안에도 제대로 반영되어있고 심지어 오늘 작업한 다른 패키지의 작업내용도 그대로 반영됐는데 왜 패키지의 그 클래스만 이클립스에 반영이 안되냐고~~~~~~~~~~~~!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

이유가 먼지 넘 궁금하다...왜 그런거야...?

 

암튼 그건 낼 강사님한테 물어보고.... 

빨리 복습을하자..결국 8시에 시작하는건 똑같네 ㅎ

 

 

오늘 배운 것은 for문이다

자바에서 탈주를 부르는 부분이라는 for문은 중요한부분인데

처음부터 이해 안된다고 포기하지말고

반복하다 보면 언젠가는 이해가 간다고 한다

 

 

반복문이란?

프로그램 흐름을 제어하는 제어문 중 하나

어떤 실행코드를 반복적으로 수행시켜준다

 

어제는 if문과 switch 문에 대해 배웠는데 얘네는 조건문이고. 오늘은 반복문!

반복문은 두 종류로 나뉨

for문/ while문 

(do wile문도 있긴 한데 강사님왈 자긴 한번도 쓴적 없다고한다)

 

 

for문이란?

어떤 실행코드를 반복적으로 수행 시켜주는게 for문의 특징이다

 

 

일단 표현법부터

for ( 초기식 ; 조건식 ; 증감식 ) {
             <반복적으로 실행하고자 하는 구문을 적는다>
               조건식이 만족하는 "동안" 반복적으로 구문 실행
}

for문이니까 for를 먼저 써주고 괄호안에 for이 돌아가게 만드는 문법? 식? 을 적는다

 

- 초기식 : 반복문이 수행 될 때 딱 처음에 한번만 실행되는 구문이다

                초기식에는 보통 반복문안에서 사용될 변수 선언과 초기화를 한다. 변수의 데이터 타입이 반드시 들어가야함

                   ex)  int i = 1;

 

- 조건식 : " 반복문이 수행될 조건" 을 작성한다

                조건식이 true일 경우 중괄호 안에 쓴 구문을 실행.처리 한다

              대부분은   초기식에 사용된 변수를 가지고 조건식을 작성

                     ex) i <= 5;   (i가 5보다 같거나 작은동안)

-증감식 : 반복문을 제어하는 변수 값을 증감시키는 구문을 작성한다

                 보통..초기식에 제시된 변수를 가지고 증감연산자를 사용한다.

                      ex) i ++;   

 

 

 

포인트는 세미콜론 두개가 꼭 있어야한다.

초기식,조건식,증감식은 생략이 가능하지만 세미콜론은 그와중에도 꼭 있어야한다~ 

 

사실 이런 이론을 달달달 외우는 것보다 한번 보고 아 글쿤 하고 계속 무한 반복을 하면서 내 눈과 머리에 익히는것이 훨씬 더 효율적이고 중요하다

 

 

예를 들어 "안녕하세요" 란 문장 5개를 출력을 하고 싶다면

System.out.println("안녕하세요");   구문을 다섯개 써서 출력할수도있지만

만약  십만개의 안녕하세요를 출력해야한다면?

현실적으로는 불가능하다. 이걸 가능하게 해주는것이 for문

위 구문을 for문으로 바꿔 쓴다면?

 

for( int i=1 ; i<=5 ; i++ ) {
             System.out.println("안녕하슈");
}

출력결과 :
안녕하슈
안녕하슈
안녕하슈
안녕하슈
안녕하슈

 

for문이 동작하는 원리?

 

위의 코드를 이용해서 설명을 함

포문은 일단 초기식 -> 조건식 -> 판단해서 true면 구문실행하고 -> 증감식 -> 다시 조건식 -> true에 구문실행 -> 증감식 -> 조건식 0> true에 구문 실행 -> 증감식 .......반복....하다가  조건식에서 false가 되면 for문을 종료함

 

구구절절 설명하면 맨 처음으로 초기식을 만나서 초기식이 수행되는데. 이 초기식은 딱 처음 한번, 지금만 실행되고 나중에 실행되지 않는다 ( i의 변수안에 1이 들어감. 1로 초기화되서 초기식이라고 한다. 현재 i 의 값은 1이다. ) 

그 다음에 두번째로 조건식을 만나 조건검사( i <=5  :  i의 값이 5보다 작거나 같은가? ) 를 한다. 그 조건식이 참(true - i의 현재값이 1이니 5보다 작은게 맞음 )라면  중괄호 안에 들어있는 구문 (안녕하슈를 콘솔에 출력)을 실행하고 ,

세번째로 증감식을 수행한다( i ++ = i값을 1 증가시킴. i의 현재값은 2) 그 다음으로 다시 반복을 하기 위해 돌아가는데 초기식 처음에만 실행되니까  pass하고 조건식으로 돌아가서 또 조건검사를한다. i의 현재값이 2이니 조건식 결과가 역시 true가 나와 구문을 출력하고 다시 증감식으로가고 또 조건검사를하고 트루니까 안녕하슈를 출력하고 또 증감식으로 i값을 1 증가시키고 를 계속 반복하다가 i의 값이 6이 되었을때 조건검사에서 false 거짓이 나오면 그때  for문은 종료가 된다!

 

결론적으로 for문은 조건식이 true 일 동안 중괄호안에 구문이 계속 반복된다는 소리.

고로 for문에서 조건식을 결정하는게 가장 중요하다.

어떠한 값이 주어졌을 때 조건식이 어떤것이 들어갈지 정하는게 가장 중요하다

 

이 동작하는 원리를 이해를 하고 for문의 예제를 써보고 반복하다보면 언젠간 이해가 된다고한다.

 

또다른 예제

 

i의 초기값이 0 일때 ,  안녕을 5번 출력해보슈

란 문제가 나오면 어케 조건식을 써야할지 뇌를 돌려보자..

 

 

안녕을 5번 출력하기 위해서는 총 반복문이 5번 돌아야한다. 그래야 5개가 출력이 되니까...

그럼 초기값이 0이니까 0 에서부터 손가락으로 세봄 왜냐?  강사님이 말해줌 헷갈리면 이케하래

영(한개..)..일(두개..)..이 (세개..)..삼 (네개..)..사(다섯개)...4에서 다섯개가 되네...

0,1,2,3,4   ->  4번까지 가야지 다섯번이 출력이 되니까

조건식이 i <=4 (i가4랑 작거나 같냐?) 또는 i <5 (i가 5보다 작냐?)가 되야한다 

왜? 5보다 작은동안임? 이해안가는데? 

왜냐면 시작하는 번호가 0이니까! !! 0에서부터 손으로세보셈 0,1,2,3,4  / 4에서 다섯개가 딱 되자너

i의 값이 5보다 작은동안~~~ 반복문을 실행해라임 

 

왜? 왜 그런지 모르겠으면 이제 하나하나 그려보는거임

 

 

 i가 0 부터 시작하면 조건식을 보고 i <=4 (i가4 보다 작거나 같냐?) 작으니까 ㅇㅋ true - 구문출력 - i 값 증감

1이되면 역시 조건에 맞으니까 ㅇㅋ 오케이  -구문출력 - i 값 증감

2도 트루 조건 만족  - 구문출력 - i 값 증감

3도 조건 충족 - 구문출력 -i 값 증감

4도 조건 충족 - 구문출력 -i 값 증감

5가 됐을 때  i <=4 ( i 값이 4랑 같거나 작냐?) 가 충족을못해서 false 거짓, 맞지않아서 for문이 그대로 종료가 된다~

 

결론

i의 값이  4보다 같거나 작은동안 (혹은 5보다 작은 동안 )반복을 해라~ 란 소리임

즉 조건식이 트루 일 " 동안 "  반복문을 실행해라~~~ 란 소리임

for 영어 단어의 한글뜻이 뭐임?  "~ 하는동안" 이잖음... 그소리임...

 

그럼 이제  또 다른 문제

 

i의 값이 11일 때 , 꺼져! 를 반복해서 5개를 출력 해보셈

조건식 어케 세우는지 모르겠다? 그럼 손을 이용해서 세어보자... 시작값이 11이니까 십일 (한개) 12(두개) 13(세개) 14(네게) 15(다섯개) 오 다섯개!  다섯개 출력하라그랬는데!  그럼 15에서 조건을 세우며 ㄴ되겠다~~~ 15랑 같거나 작은동안 / 혹은 16보다 작은동안 (15까지는 실행을하고 그 이후는 빠져나가라~,실행하지마라~) 실행을 하라는 조건을 세우면 되겠구만..! 하고 얼레벌레  for문을 작성해본다 

 

for ( int  i = 11  ;  i <=15  ; i++ ) {
  System.out.println("꺼져!");
}

int  i = 11 ( int형 변수 i가 11일때)  ;  i <=15 ( i가 15보다 작은동안 반복을해라) ; i++ ( 구문실행하면 i의 값을 1 올려라) {

  System.out.println("꺼져!");

}

 

 

흠..아직 모르겠다...?

하면 이제 알때 까지 예제를 겁나게 반복 반복 반복 해보는것임

 

다음예제

i의 초기값이 1 일때  10번 동안 두개씩 증가하는 배고파를 출력하는 for문을 작성 해보슈

 

초기값이 1? 그러면 int i =1 ; 이겠고~

두개씩 증가?  그럼 i 에다가  2를 더하면 되겠군. 그럼 2씩 증가하는거니까

i = i +2 를 하면 되는데..아 이거 몬가 익숙한데 아 저번에 배웠지 복합대입 연산자! 

i += 2    ( i를 2씩 더하면서 그 값을 i에 넣음)

10번동안? 그럼 1부터 시작하니까 10보다 같거나 작은동안~ 혹은 11보다 작은동안이라고 조건을 적으면 되겟군

i < = 10;   혹은 i <11  이겠다~

 

for ( int i = 1; i <=10 ; i += 2){

       System.out.println("배고파");

}

 

 

아 이제 몬가..좀...대충은 알겠어

여기 까지 이해하는건 머 갠찮음...그렇게까지 어려운거아님

같은 글자 몇번 내보내기 ? 아 쌉가능

그럼 이제 숫자를 증가시키면서 그 값을 출력해보기를 해보는거임

 

1~5 까지 하나씩 증가하면서 그 올라가는 값을 반복 출력 해보셈

 

모야..어케해..하지만 하나씩 뜯어보면 할수있음

 

일단 1에서부터 5니까 시작값,초기값이 1이구만

int i = 1; 

그다음 5까지니까 i <=5 혹은 i <6

그다음 하나씩증가하랬으니  i++  

근데 이제 출력을 어케하냐~?

중괄호 안에 

sysout( i );

i변수를 넣어주는거임...

왜? 위의 조건식에서 i가 1부터 시작해서 하나씩 5까지 올라가잖아~

그 값을 그냥 구대로 출력 때리는거임...

아그런가..? 그런가...? 그런거같네 하고 넘어가 

for (int i = 1; i<=5; i++) {
			System.out.println(i);
		}
        
<출력값>
1
2
3
4
5

 

어 근데 1씩 증가해서 값을 출력도 가능하니

값을 더한 값도 출력이 되것는디...? 라는 배우신분의 생각..

 

1~10 까지 값을 1씩 증가시켜  증가시킨 값을 누적해서 합을 구해보자!

 

긍까...값을 1씩 증가시키는데!!!!!  1,2,3,4,5 ...그 값을 더하고 더하고 더한 누적 값을 알아보는거임

 

그럼 일단 sum 변수를 하나 선언해놓음...

왜? 합계한 값이 들어갈 곳을 만들어줘야 그 값을 보여줄거아님...?

int sum  = 0; 

그럼 for문을 하기 전에 한번...먼저 생각해보는거임 

 

첨엔 sum 에는 0이 있잖음 근데 i는 1부터 시작하잖음 그럼 이걸 더해서 누적하라는거잖음?

첨엔 0 + 1 이되고 그 값을 sum에 담아서  sum 은 1이 됨

그럼 또 i++로 1이 증가되서 i값이 2가 되고 

다시    1 + 2 를 sum 값에 담음      =>  이걸 그대로 써보면?

sum = sum + 1

sum = sum + 2

sum = sum + 3

그럼 복합대입 연산자 배웠으니까 짧게

sum += 4

sum += 5

sum += 6

 

오오...보니까 뭔가 계속 반복되는게 있꼬 (sum = sum +)  변하는 값(1,2,3,4,...)이 있음

그럼 이걸 고대로 for문에적용하면!!!

반복되는 구문은  중괄호 안에 그대로 넣고......왜? 계속 똑같이 반복이 되니까~

변하는 값은 i 로 하자는 것임

그러면

sum += i ;

가 된다는 것입니다...

		for(int i=1; i<=10; i++) {
			sum += i;  
		}
		System.out.println("1부터 "+num +"까지의 합 : " +sum);
	}

 

왜? 왜 이렇게하냐고...? 반복되는게 귀찮아서 그냥 한번의 코딩으로 한번에 처리하겟다는게 for문의 목적.

중복된 코드를 극혐하는 java의 방법....모르면 그냥 반복

sum += i ; 이 문장이 죽어도 이해안간다?

그냥 외우라고 강사님이 말씀해주셨다

편 - 안 

이해 안가면..최대한 풀어..풀어...엉킨실을 풀듯이 최대한 일일히 하나하나 풀어서 보도록....

 

 

 

 

그리고 랜덤값 구하는것도 배웠다

 

Math 클래스를 이용한 랜덤값 추출하기

 

자바에서 제공하는 Math 클래스안에 랜덤값을 구하는 메소드가 하나 있음

어케쓰냐면

Math.random();

하면 써지는데 이건 Math 클래스의 random() 메소드를 호출하겠다고 하는거임

이클립스에 Math. 하고 점을 치는 순간 자동완성으로 사용할수있는 Math클래스내의 메소드들과 변수들이 보여져지는데 우리는 그 들 중 random()을 쓰는거다.

 

나는 1~10 사이의 랜덤값 한개를 뽑아서 int형 a 변수에 담고싶음. 일단 변수부터 선언

int a = 0;   

 

random() 메소드를 호출하면

우리는  0.0 에서 0.99999999(무한) 사이의  실수형의 랜덤값을 얻을 수 있음.

근데 우리가 원하는건 정수 1~10까지의 수임. 

일단 메소드에 곱하기 10을 하면됨 (45까지 받고싶으면 *45) 

(Math.random() *10)

왜????   

0.0 에서 0.99999999(무한) 이였던 값이 0.0~~~~9.9999999(무한)이 되는거임

근데...? 애매해...나는 1~10 까지의 랜덤값이면 좋겠는데...저 숫자 모임...그럼 저기서 어케해야 1~10에 가까워지겠음?

(Math.random() *10)해서 0.0~~~~9.9999999(무한)  여기에 1을 더하면 됨 

(Math.random() *10 +1) 그러면 1.0~~~~~10.99999  값 범위가 되는거임

근데 실수형 이잖음뒤에 소수점만 없애버리면 되는데...어차피 int형 변수에 값을 담아야되기도하고 해서 int형으로 형변환을해주면!  뒤에 소숫점은 자동으로 떼짐....왜? int형(정수)으로 바뀌면 소수점이 걍 날라가니까...소수점이 없어야 정수형이죳!

(int)(Math.random() *10 +1) 

 

int a = (int)(Math.random() *10 +1); 
System.out.println("1~10사이의 랜덤값 : " + a);
// 만약 1~100 사이의 랜덤값을구하고싶다? 그럼 *100 하고 +1 해주면 되는거임
//int a = (int)(Math.random() *100 +1);

 

설명은 구구절절했지만 랜덤값 구하기 코드의  결론은 이것이다... 

걍 정수값을 랜덤으로 구해주는 메소드는 없음? 네 없음. 

왜 없는지 모를? 그래서 이케 다들 쓰고 있다고함. 

 

근데 for문하는데 이걸 왜 배웠지? 

이걸 for문 조건식에 넣어 볼 수 있다는 것임 ^^

(근데 랜덤값은 어차피 다른곳에서도 엄청 많이 씀)

 

랜덤값을 추출해 1에서부터 랜덤값까지의 합계를 구하는것을 위한 빌드업이였다! 

짜보셈 저 랜덤값을 뱉어주는 a를 이용해서... 

 

int a = (int)(Math.random() *10 +1); 
int sum = 0;

for(int i=1; i<=a ; i++) {  
	sum += i;
}
  System.out.println("1부터 " +a +"까지의 합계 : "+sum);

포인트 ->

반복출력되면 안되는 출력문은 for문 밖에다가 쓴다. 

랜덤값은 어케 구하는가?

조건문에 왜 a 가 들어가는가? 

합계 값은 어케 구하는가?

 

 

 

 

이제 문자열 인덱스를 이용한 for문 활용을 해보겠음

 

 

for문을 이용해서 문자열을 한개한개씩 출력해보겠음

 

String str = "Hello";

String타입 str 변수에 Hello 문자열이 담겼음 
각 인덱스별 문자를 뽑아 출력을 해보자면?

인덱스의 시작번호는 0임. 모든 인덱스는 0부터 시작함 

 * H => str.charAt(0);  (str변수의 0번째 인덱스 출력 => H)
 * e => str.charAt(1); (str변수의 1번째 인덱스 출력 =>e)
 * l => str.charAt(2); (str변수의 2번째 인덱스 출력 => l)
 * l => str.charAt(3); (str변수의 3번째 인덱스 출력 => l)
 * o => str.charAt(4); (str변수의 4번째 인덱스 출력 => o)

 

 * 0번 인덱스부터 4번인덱스(마지막 인덱스)까지 매번 1씩 증가하면서 반복을 수행해야한다

 

포인트 -> str.charAt()이 반복되고 인덱스 속 숫자가 변함을 파악함
반복문이 써지는 중괄호에에 반복되는것들이 들어가고 역동적으로 바뀌는것들이 i가됨 

for(int i=0 ;i <= 4; i++) {
          System.out.println(str.charAt(i));
}

 

출력

H

e

l

l

o

 

 

 

이제 구구단을 출력해보겠음

2단 출력을 해보자 

다까먹어도 구구단하는 방법은 알고가자

 

이런식으로 출력을 하고싶음

2 x 1 = 2

2 x 2 = 4

....

2 x 9 = 18

 

여기서 변하지 않고 계속 반복되는것은 무엇인지

계속 변하는 것은 어느것인지 파악을 한다. 

2 x  =   은 안변하고

1~9 와 값이 변함

규칙을 찾아냄. 초기값은 무엇인지, 어디까지 나와야하는지, 얼마씩 증감하는지 

1부터 시작해서 9까지 한개씩 증가한다는 것을 파악한 후 for문 작성

for(int i = 1; i <= 9; i++) {  // i가 1부터 시작해 9와 같아질때까지 i를 한개씩 증가 반복함
     System.out.printf("%d x %d = %d\n", 2, i , 2*i);
	//혹은 System.out.println("2 x " +i+ " = " + 2*i);
}

 

 

좀 더 발전된 구구단 작성

사용자에게 출력하고 싶은 단을 입력 받아 구구단을 출력해보자 

1) 사용자에게 단을 입력받을 문구를 보여주고 정수로 출력단을 입력받음

2) 2~9 사이의 숫자만을 입력받을 수 있음

3) 다른 숫자를 입력했을 경우 2~9사이 입력해야한다고 출력 

 

Scanner sc = new Scanner(System.in);

System.out.print("2~9 사이의 숫자를 입력 : ");
int dan = sc.nextInt();
	
if(dan>=2 && 9>=dan) {
	for (int i=1; i<=9 ;i++) {
		System.out.printf("%d x %d = %d\n",dan,i,(dan*i) );
		//System.out.println(dan+" x "+ i+ " = "+(dan*i)); 이렇게도 가능
	}
}else {
	System.out.println("2~9 사이의 숫자를 입력해야 됩니다.");	
}

지금까지 배운게 짬뽕되어있음

if문으로 2~9 사이의 값만 통과될 수 있도록 조건을 작성하고

for문으로 구구단을 돌림 

 

 

업그레이드 for문

< 2~9까지 랜덤값을 발생시켜서 랜덤단 출력하기>

 

int dan = (int)(Math.random() *8 +2);

//+2가 시작하는 수, 시작수로 부터 몇개의 랜덤을 발생시킬꺼?

여기서 랜덤값 구하기의 공식을 알 수 있음

2~9까지의 랜덤값을 얻고 싶다면

(int)(Math.random() *8 +2);

(int)(Math.random() *m +n);

2가 시작수니까 +2를 해주면 2부터 시작수인거임 -> +n   n부터 시작함

2부터 8개의 수의 랜덤값이 나온다 기억해야함. -> n에서부터 m개의 랜덤값이 나온다 

 

int dan = (int)(Math.random() *8 +2); 

System.out.println("==== "  + dan +"단 ====");
for(int i = 1 ; i<=9 ; i++ ) {
	System.out.printf("%d x %d = %d\n", dan, i, dan*i);
}