🌞 Day 004 : 연산자, 제어문

  • 오늘은 연산자 중에서도 비교연산자, 논리연산자를 조합해서 코드를 만드는 것을 배웠다. 그리고 if문을 배우고 if문의 조건에 연산자를 조합한 연산식을 넣고 다양한 코드를 만드는 법을 배우고 연습했다.

 🪐 1 교시 

  • 관계연산자(비교연산자)
    • 좌항기준
      > (초과), < (미만),
      >= (이상≥), <= (이하≤),
      == (같다), !=(같지 않다)
    • 좌항과 우항의 크기를 비교하여 true/false 값이 결과가 되는 연산
    • 관계식이 올바른 경우 결과값이 true, 틀린 경우 false

  • 문자(char) 데이터 간의 비교

  • String의 비교

    • “1234” VS “987”
      위의 둘을 비교하면 “987”이 크다 어제 정리한 것처럼 첫 글자부터 하나씩 비교하기 때문이다.
      "1234"와 "987"을 비교한다면 첫글자인 1과 9를 비교한다는 뜻
      그러나 숫자형이나 char처럼 변수에 넣어서 비교 연산자로 비교하면 에러가 난다.

    • 위의 코드블록에서 s1과 s2는 기본 자료들과는 달리 조금 특별한 자료형이며(Stirng), 이 두 변수가 직접 문자를 저장하고 있지 않다.
      문자들은 별도의 장소에 저장하고, 변수에는 그 문자들의 위치정보(주기억장치 내 위치)값을 저장한다.
      그나마 사용 가능한 연산자는 ==, != 는 사용이 가능.
      (즉, 같은지 다른지만 비교할 수 있다)
      그래도 숫자형이나 char처럼 ~보다 크다 / 작다 라는 비교는 할 수 없다.
      그래서 ==, != 연산이 에러없이 가능은 하지만 이도 사용을 하지 않습니다.

    • 그래도 String 자료 간의 비교를 하고 싶다면 별도로 만들어져 있는 도구를 이용해야 한다.
      string.compareTo();
      string.equals();

 🌱 String의 크다 작다를 판단해주는 .compareTo() 

  • compareTo의 결과는 정수 이다.
    이 정수는 맨 첫 글자부터 비교했을 때, 처음으로 같은 글자가 아닌 곳에서 앞 글자에서 뒤에 글자를 빼는 산술연산(아스키코드 값들의 연산)을 해서 얻은 결과이다.
    위 코드블록처럼 "1234"와 "987"을 비교하면 첫글자가 설로 다르므로 1과 9를 비교한다.
    코드 첫 줄은 '1'아스키코드 값에서 '9'아스키코드 값을 빼면 -8이 된다.
    그래서 r의 값을 출력하면 -8이 출력되는 것이다.
    세 번째 줄에서는 s1("1234")과 s2("987")의 순서를 바꿔서 비교하므로 '9' - '1'의 값이 변수 r에 저장되므로 출력하면 양수 8이 출력된다.
  • .compareTo()에서는
    결과가 양수이면 앞쪽 글자가 크다, 음수이면 뒤쪽 글자가 크다 라고 표현
    둘의 글자들이 정확히 모두 일치하면 결과는 0이다.
  • 응용해보기

 🌱 String의 같다 다르다를 판단해주는 .equals() 

  • String 간의 비교를 하면서 같은지 다른지 비교를 하고 싶을 때 ==를 쓰면 안된다. (JS에서는 가능했으므로 헷갈리지 않게 조심하자)
  • "1234"와 "987"을 .eauals()를 사용하여 비교해보자

 🪐 2 교시 

  • 논리연산자 &&(AND), ||(OR), !(NOT)
    - 다수 개의 관계(비교)연산식 결과 (true/false)값을 대상으로 연산하여 하나의 boolean 값을 얻는 연산
    - 피연산자 : boolean, 연산의 결과 : boolean
  • AND 연산 - &&
    좌항 우항 모두 true 일 때만 true이고, 나머지는 모두 false
    즉, 좌항 우항 하나라도 false 이면 결과는 false

  • OR 연산 - ||
    좌항과 우항 중 하나라도 true가 있다면 결과는 true
    둘 다 모두 false 일 때 결과가 false가 된다

  • NOT 연산 - !
    단항연산(피연산자 1개)
    true / false 값을 현재 값의 반대로 변경하는 연산

  • 입력받은 정수(점수)가 50이상이면서 100이하면 true, 그렇지 않으면 false

  • 100 이상 이거나, 40 미만 true, 아니면 false


 🪐 3 교시 

 🔖 연습 문제 

 🔖 연습 문제 

  • 문제 1 : 세 과목의 성적으로 비교연산자, 논리연산자 연습하기

  • 응용 1 : 짝수? 홀수?

  • 응용 2 : 윤년 계산기 만들기

  • 위의 내 코드에서 굳이 B, C부분을 묶어줄 필요가 없었다.
    4교시에 강사님의 답 해설을 보니 ( )로 묶지 않았는데 연산자의 우선순위를 보면서도 헷갈려서 다시 연속된 논리연산자의 식을 검색해보고 다른 사람들의 포스팅을 읽으니 이해가 되었다.
    오후 수업의 연습 문제에서 다시 윤년 계산식을 사용하는 문제가 있었다.
    그 연습문제 아래에 내가 이해한 방식으로 정리해 두었다.

 🪐 4 교시 

  • 캐스팅 연산 & 자료의 형변환
    • 정수 데이터에 별도의 표시(100L) 없다면 그 데이터는 int형 데이터
    • byte 변수에 int형 자료를 대입하는 동작은 원래는 에러를 발생하고 캐스팅 연산이 필요하지만 정수에 한해서만 생략 가능
    • byte b1 = (byte)100; 원래 이렇게 써야 맞음
    • 생략이 가능한 것은 단순 정수데이터를 정수형(byte, short)변수에 대입(연산X)하는 동작까지만 가능

  • b3의 값은 220이다 그런데 갑자기 음수가 출력된다
    그 이유는 byte의 범위를 넘었기 때문에 (-128 ~ 127)

  • byte의 범위를 넘어서면 이렇게 출력된다.
    위에 있는 숫자가 출력될 때는 아래에 있는 숫자로 출력됨
    입력 : 127   128   129   130   131
    출력 : 127  -128  -127  -126  -125

  • -128 ~127이 동그랗게 줄서있다고 생각해보자
    범위 안의 수라면 자신의 자리에 들어가면 된다. 그런데 넘어간다면?
    128은 자기 자리가 없다 127 다음의 자리에는 -128의 자리이다.
    따라서 128은 출력될 때 -128로 출력되는 것이고,
    위 블록의 경우 220은 자기 수만큼 빙빙 돌다가 멈춰보니 -36자리 였던 것


  • int ➡️ double   /   double ➡️ int

  • char ➡️ int   /   int ➡️ char
    그리고 그 밖의 캐스팅연산

  • String -> int
    아라비아 기호로만 구성된 Stiring을 int형으로 변환
    • 잘못된 예
       String s1 = "1234"
       int a4 = (int)s1; (X) ⇒ ERROR!!! 
      String 변수에 저장된 문자들이 사용되는 때는 다른 자료와 연산할 때이지만, 위의 코드처럼 혼자 연산될 때에는 문자들이 저장된 위치 정보가 사용된다.
      따라서 위의 코드가 에러가 나는 것!

      반대의 경우도 에러
       int a5 = 123456;
       String str2 = (String)a5; (X) ⇒ ERROR!!!

 🌱 Integer.parseInt(String), String.valueOf(Integer) 

  • 호환되지 않는 자료들 간의 형변환은 별도의 도구(메서드)가 필요합니다.
    • String -> int
      Integer.parseInt(s2)
    • int -> String
      String.valueOf(a7)

  • String -> char 일 때는 주의해야 한다!!


 🪐 5 교시 

 🌱 제어문 (Control_Op) 

  • 프로그램 실행의 순서에 관여하는 연산자 (뛰어넘거나, 반복하거나 등등)
  • 사용자로부터 정수 하나를 입력 받아서 짝수인지 홀수인지 출력하고 싶을 때
    이전 예제처럼 짝수, 홀수 상태를 T/F 로 출력하는 것이 아니라
    정확히 "짝수입니다." or "홀수입니다."로 출력할 예정

  • if문의 특징

    • ()안의 연산의 결과 또는 값이
      true이면 {} 안의 명령을 실행, false이면 실행하지 않는 명령
    • ()안의 값이 true 이면 실행해야 할 명령이 두 개 이상일 수 있으므로, {}로 그 경계를 구분 (실행하거나 실행하지 않을 영역 구분)
    • ()안의 값이 true 일 때 실행할 명령이 한 개라면, {}를 생략할 수 있다.
    • 만약 ()안에 일부러 true를 썼다면 -> if(true) { }
      {}안의 내용은 무조건 실행
    • 반대의 경우 if(false){ } 무조건 { }안의 내용을 실행하지 않고 건너뛴다.
    • ( )안에는 비교연산과 논리연산이 조합된 복합연산식 표현이 가능
       if ( (x==0)& (y!=0)||(z==0) ) { } 
    • ( )안에는 비교연산대신 true/false 값을 갖고 있는 boolean 변수도 들어갈 수 있다.
  • 명령이 하나만 있는 if명령은
    if부터 한 개의 명령 뒤에 세미콜론까지가 하나의 문장으로 인식
    그래서 세미콜론도 마지막에 한 번만 사용
    명령이 여러개여서 중괄호가 사용되면 따로 if문자에 세미콜론은 사용하지 않고, 중괄호 안의 각 명령들에만 세미콜론을 붙인다.

  •  초보가 자주 실수하는 문장들 
    •  if(b==0);  여기서 문장이 끝나버림 다음 명령들이 if와 상관없는 명령이 되어버림
    • 입력한 숫자가 40보다 크고 80보다 작은 경우
       40 <= a <=80 (X)  안됨!! 한 번에 하나씩
       a>=40 && a<=80 (O) 
  •  else if 


 🪐 6 교시 

 🔖 연습 문제 

  • 문제 1 : 합격 / 불합격 출력하기

  • 문제 2 : 윤년 / 평년 판별기

  • result = (year%4==0)&&(year%100!=0)||(year%400==0);
    에서 뒤에 두 개를 안 묶어도 윤년의 조건을 만족하는가? 라는 의문이 생겼다.
    아마 내가 여기서 글로된 조건을 논리연산으로 바꿀 때 조금 헷갈린 부분이 있었던 것 같다.
    그래서 혼자 &&와 ||을 연속해서 써보고 출력해보고 또 다른 사람들의 정리된 글을 읽으면서 이해를 했다.

  • 아마 차근차근 생각했으면 혼란스럽지 않았을 텐데 빠르게 나가는 수업을 들으면서 생각하려니 순간 헷갈렸던 듯
    어쨌든 이 문제로 인해서 논리연산과 연산자들의 계산순서를 더 잘 이해하게 되었다.

  • 내가 배운 것
    ||의 특징 때문이었다. 굳이 ( )로 묶을 필요가 없는 이유 ||는 앞이 true이면 ||연산자는 뒤의 항은 확인 하지 않는다. (값이 뭐든 true니까)
    그래서 ||와 &&가 연속할 때 ||가 앞에 있는 뒤에있든 &&으로 묶인 단항이 true이면 true가 되어버림
    즉, 위의 블록에서 굵은 글씨가 T인 이상(그리고 || 앞 뒤가 FF가 아닌 이상) 저 연산은 true가 되어버린다.

  •  다시 정리하면 
    result =  (year%4==0) && (year%100!=0)||(year%400==0); 
    (year%100!=0)||(year%400==0) 여기를 굳이 묶을 필요가 없다.
    간단하게 A && B || C 로 표기 하면
     A가 T 일 때 (2 가지로 나뉜다.) 
              B가 T 일 때 : 여기까지 이미 T라서 C는 볼 것도 없이 T
              B가 F 일 때 : 여기가 F라도 C가 T라면 T
        A가 T 일 때 ⇒ B,C가 둘 다 F일 때만 제외하고 전체는 T가 된다. 
     A가 F 일 때  &&연산에서 뒤까지 갈 것 없이 이미 F
    결론 : B,C를 묶을 필요가 없음

  • 연산의 우선순위 (같은 우선순위끼리는 앞에서 순서대로)
    1. ( )
    2. 변수의 앞에 사용되었다는 가정하에 ++, --
    3. 곱셈 나눗셈 나머지(%)
    4. 덧셈 뺄셈
    5. 비교(관계)연산
    6. 논리 연산
    7. 대입 연산
    비교가 논리보다 먼저 계산


 🪐 7 교시 

  • 다양한 else-if문

 🔖 연습 문제 

  • 문제 1 : 평균이 80이상이면 합격, 70이상 79이하면 대기순번, 나머지는 불합격

  • 문제 2 : 연속된 else if

  • 위와 아래는 같으나 차이점 : 특히 구간을 여러 개 나눠서 작성하는 경우
    위처럼 범위를 정확히 해주는 편이 좋다.
    아래처럼 쓰면 간단하지만 실수할 확률이 높다.
    코드 실행은 위부터 차례로 내려오기 때문에 잘못된 구간에서 멈출 수도 있다.

 🪐 8 교시 

 🔖 연습 문제 

  • 문제 1 : 출생년도를 입력 받아서 조건에 따른 "문자열" 출력하기

  • 문제 2 : 아래 블록 참조

  • 문제 2의 답 (내가 쓴 답)

  • { }안의 명령문들을 보면 total=pay+(int)(pay*r); 라는 코드가 반복이 된다.
    반복되는 것이 싫어서 if문 밖으로 꺼냈더니 이클립스에 경고가 떴다.
    정확히는 모르겠지만 변수 r에 값이 대입이 안되서 그런 것 같아서 다시 if문의 { }마다 넣어주었다.
  • 또 이상했던 점은 처음에 total=pay+(int)(pay*r);total=+(int)(pay*r)+pay;이렇게 쓰고 실행했을 때 이상한 값이 출력됬었다.
    연산식의 순서를 바꾸고 정상실행되는 듯 했으나 원인을 모르겠다.
    식이 형변환에서 문제가 있었는지 숫자를 잘못 입력했는지 확실하지 않았다.
  • 문제를 푸는 도중 6시가 넘어서 이 문제의 답과 해설은 내일 수업에서 하기로 하고 오늘 수업이 끝났다.



 ✅ 마무리 하면서... 

  • 비교연산과 논리연산의 조합은 예습했었음에도 헷갈리고 어려웠다.
    연산식이 길어지고 복잡해질수록 차근차근 끊어서 읽어야겠다.
  • 복잡한 연산식을 if문까지 결합하니 코드도 길어지고 복잡해져서 코드를 읽고 쓰는데 정신을 바짝 차려야 겠다고 생각했다.
  • 확실히 먼저 문제를 풀어보고 강사님의 코드와 비교해보니 내 코드에 쓸데 없이 붙은 부분이 많은 것 같다. 좀 더 간결하게 정확하게 코드를 쓸 수 있도록 연습을 해야 겠다.
profile
제가 공부하고 공유하고 싶은 글을 올리고 있습니다.

0개의 댓글