작년에 멋쟁이사자처럼 직장인 과정에 참여하면서 파이썬을 조금 공부했었기 때문에 구구단 코드를 짜는데 큰 어려움이 없을거라고 생각했다. 큰 틀은 유사한 면이 있어서 이해하는데 어려움은 없었지만, 역시 언어가 달라서 생소한 문법들이 많았던 데다가 에디터를 vs code를 쓰다가 IntelliJ로 바꿔서 개발 환경이 달라져서 적응하느라 애를 먹었다. 여전히 바뀐 개발환경에 적응 중이고 IDE에 관해서는 계속 이것저것 만져보면서 학습한 과정을 따로 포스팅할 예정이다.
현재 듣고 있는 강의는 인프런 박재성 님의 '만들어 가면서 배우는 JAVA 플레이 그라운드'이다. 이 강의는 문법을 하나하나 알려주면서 이론부터 차근차근 학습하는 것이 아니라 실전 예제를 통해 직접 만들어 보면서 그 때 그 때 필요한 문법을 가져다 쓰는 특징이 있다. 강의를 들어도 문법의 정확한 용도를 알 수는 없고, 자발적으로 구글링을 통해 학습해야 한다. 강의를 들으면서 모르는 것을 구글링으로 학습한 후 포스팅을 할 예정이고, 문법을 deep하게 들여다보기 보다는 조금 부정확할지라도 가려운 부분만 긁고 넘어가는 수준으로 빠르게 전체적인 숲을 한번 훑어본 후에 부족한 점을 채워나가는 식으로 공부할 것이다.
public class Gugudan {
public static void main(String[] args) {
System.out.println(2 * 1);
System.out.println(2 * 2);
System.out.println(2 * 3);
System.out.println(2 * 4);
System.out.println(2 * 5);
System.out.println(2 * 6);
System.out.println(2 * 7);
System.out.println(2 * 8);
System.out.println(2 * 9);
}
}
public은 접근 제어자라는 문법중 하나이다. ( 앞으로 빨간색 글씨는 정확하게는 모르지만 어느정도 이해하고 넘어가는 문법이다. 나중에 자세히 학습하게 되면 따로 포스팅을 한 후 빨간색 글씨를 지워나갈 것이다.) 접근제어자 문법을 만든 이유는 외부에서 잘못 변경되는 것을 막기 위함이다.(무슨 말인지 잘 모르겠다.) 접근제어자는 4가지 방식이 있고 public, private, protected, default가 있다.
void의 뜻은 빈 공간으로, void의 역할은 아무것도 return할 것이 없음을 선언하는 문법이다.
앞의 system이 뭔지는 잘모르겠지만 out은 출력을 의미하는 것 같다. 파이썬에서는 출력으로 printf를 사용했는데 자바에서는 println이라는 걸 사용해서 새롭게 느껴졌다. 밑에 더 포스팅을 하겠지만 나중에 구글링을 통해 자바에서도 printf를 사용할 수 있다는 것을 알게 되었다.
import java.util.Scanner;
public class Gugudan {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int dan = scanner.nextInt();
System.out.println("몇 단을 출력하시겠습니까?");
int result = dan * 1;
system.out.println(result);
result = dan * 2;
system.out.println(result);
result = dan * 3;
system.out.println(result);
result = dan * 4;
system.out.println(result);
result = dan * 5;
system.out.println(result);
result = dan * 6;
system.out.println(result);
result = dan * 7;
system.out.println(result);
result = dan * 8;
system.out.println(result);
result = dan * 9;
system.out.println(result);
}
}
입력 문법 Scanner를 사용하기 위해서는 프로젝트에 Scanner를 불러와야지만 사용할 수 있다. 파이썬에서는 import까지 하지는 않았던 걸로 기억하는데 java에서는 입력도 import를 하는 것을 알게 되었다.
Scanner는 입력을 사용하기 위한 class이고, scanner은 내가 지정한 클래스 이름이다. 다른 이름을 사용해도 된다.
result라는 내가 지정한 변수 안에 결과값을 int(integer,정수형)의 형태로 저장한다는 의미이다. 후에 result라는 변수에 다른 값을 덮어 써서 다시 사용하려면 int만 빼면 된다.
import java.util.Scanner;
public class Gugudan {
public static void main(String[] args) {
System.out.println("몇 단 출력?");
Scanner scanner = new Scanner(System.in);
int dan = scanner.nextInt();
int i = 1;
while (i < 10) {
System.out.printf("%d * %d = %d\n",dan, i, dan*i);
i++;
}
}
}
import java.util.Scanner;
public class Gugudan {
public static void main(String[] args) {
System.out.println("몇 단 출력?");
Scanner scanner = new Scanner(System.in);
int dan = scanner.nextInt();
for (int i=1; i<10; i++) {
System.out.printf("%d * %d = %d\n",dan, i, dan*i);
}
}
}
둘 다 반복적으로 코드를 작성해주는 문법이다. 굳이 유사한 여러 코드를 직접 타이핑할 필요가 없다. 둘의 차이는 for문은 보통 반복 횟수가 정해져 있고 while문은 조건을 만족시킬 때까지 반복한다. 문법 자체는 while문이 반복조건만 명시되어 있어서 더 직관적이다.
강의에서는 println으로만 코드를 짜서 구구단의 결과값만을 출력했다. 결과 값과 함께 곱셈 식도 출력하고 싶어서 파이썬에서 배웠던 printf를 혹시나 해서 사용해봤는데 역시 java에도 printf를 사용할 수 있었다. printf(print formatter)와 println(print line)의 차이는 printf는 println은 출력 후 한줄 띄우기이고 printf는 변수의 값을 다른 형식으로도 출력할 수 있게 해주는 문법이다. printf를 사용하면 구구단이 1줄로 출력되기 때문에 python을 공부할 때 배웠던 한 줄 띄우는 문법인 \n을 사용하였다.
import java.util.Scanner;
public class Gugudan {
public static void main(String[] args) {
System.out.println("몇 단 출력?");
Scanner scanner = new Scanner(System.in);
int dan = scanner.nextInt();
if (2 > dan | 9 < dan) {
System.out.println("구구단은 2단부터 9단까지 입니다.");
}
else {
for (int i=1; i<10; i++) {
System.out.printf("%d * %d = %d\n",dan, i, dan*i);
}
}
}
java는 python과 다르게 'a < x < b' 와 같은 부등호식을 사용할 수가 없다. 'a < x & x < b' 와 같이 표현해야만 한다. 그리고 and, or도 사용할 수가 없는 것 같다. &, |를 사용해야 한다.
public class Gugudan {
public static void main(String[] args) {
int[] result = new int[9];
for (int i=0; i<result.length; i++) {
result[i] = 2 * (i + 1);
}
for (int i=0; i<result.length; i++) {
System.out.println(result[i]);
}
int[] times3 = new int[9];
for (int i=0; i<times3.length; i++) {
times3[i] = 3 * (i + 1);
}
for (int i=0; i<times3.length; i++) {
System.out.println(times3[i]);
}
int[] times4 = new int[9];
for (int i=0; i<times4.length; i++) {
times4[i] = 4 * (i + 1);
}
for (int i=0; i<times4.length; i++) {
System.out.println(times4[i]);
}
}
}
배열이란 동일한 자료형의 데이터를 연속된 공간에 저장하기 위한 자료구조이다. 연관된 데이터를 그룹화하하여 묶어준다고 생각하면 된다.
result라는 변수에 크기가 9(0~8)인 배열을 만들었다는 뜻이다.
result라는 변수의 크기를 뜻한다.
첫 for문은 result라는 변수의 각 배열에 반복문을 이용하여 구구단 결과값을 하나하나 넣어주는 것이고, 두번째 for문은 각각의 배열에 들어간 결과값을 하나하나 출력해주는 것이다.
for문 두 개를 합쳐도 같은 결과가 나오는데 왜 굳이 결과값을 배열에 저장하는 부분과 결과값을 출력하는 부분을 나눠놨는지 모르겠다.
public class Gugudan {
public static void main(String[] args) {
int[] result = new int[9];
for (int i=2; i<=result.length; i++) {
for (int j=0; j<result.length; j++) {
result[j] = i * (j + 1);
}
for (int j=0; j<result.length; j++) {
System.out.printf("%d * %d = %d",i,(j+1),result[j]);
}
System.out.println();
}
}
}
바깥 for문은 단수(2~9)를 뜻하고 안쪽의 두개의 for문은 하나는 결과값을 배열에 각각 넣은 것이고 다른 하나는 그 결과값을 각각 출력한 것이다. 마지막 문장은 단별로 구분짓기위해 임의로 띄어 쓰기를 한 것이다.
//5번 코드
public class Gugudan {
public static void main(String[] args) {
int[] result = new int[9];
for (int i=0; i<result.length; i++) {
result[i] = 2 * (i + 1);
}
for (int i=0; i<result.length; i++) {
System.out.println(result[i]);
}
int[] times3 = new int[9];
for (int i=0; i<times3.length; i++) {
times3[i] = 3 * (i + 1);
}
for (int i=0; i<times3.length; i++) {
System.out.println(times3[i]);
}
int[] times4 = new int[9];
for (int i=0; i<times4.length; i++) {
times4[i] = 4 * (i + 1);
}
for (int i=0; i<times4.length; i++) {
System.out.println(times4[i]);
}
}
}
// calculate method 작성
public class Gugudan {
public static int[] calculate(int times) {
int[] result = new int[9];
for (int i=0; i<result.length; i++) {
result[i] = times * (i + 1);
}
return result;
}
public static void main(String[] args) {
int[] result = calculate(2);
for (int i=0; i<result.length; i++) {
System.out.println(result[i]);
}
int[] times3 = calculate(3);
for (int i=0; i<times3.length; i++) {
System.out.println(times3[i]);
}
int[] times4 = calcalate(4);
for (int i=0; i<times4.length; i++) {
System.out.println(times4[i]);
}
}
}
// print method 작성
public class Gugudan {
public static int[] calculate(int times) {
int[] result = new int[9];
for (int i=0; i<result.length; i++) {
result[i] = times * (i + 1);
}
return result;
}
public static void print(int[] result) {
for (int i=0; i<result.length; i++) {
System.out.println(result[i]);
}
}
public static void main(String[] args) {
int[] result = calculate(2);
print(result);
int[] times3 = calculate(3);
print(times3);
int[] times4 = calcalate(4);
print(times4);
}
}
public class Gugudan {
// 결과값을 배열에 저장
public static int[] calculate(int times) {
int[] result = new int[9]
for (int i=0; i<result.length; i++) {
result[i] = times * (i + 1);
}
return result;
}
// 배열에 저장된 결과값을 출력
public static void print(int[] result) {
for (int i=0; i<result.length; i++) {
System.out.println(result[i]);
}
}
// main method
public static void main(String[] args) {
for (int i=2; i<10; i++) {
int[] result = calculate(i);
print(result)
}
}
}
메소드란 특정 작업을 수행하기 위한 명령문의 집합을 의미한다.
위에서 설명한 대로 void는 return 값이 없다는 의미인 반면 여기서는 result 값을 반환해야하기 때문에 result 값의 형태인 배열(int[])를 작성한 calculate라는 이름의 method이다.
5번과 비교하면, 단수마다 일일히 result 배열에 결과값을 넣는 작업을 반복했었다. 이번엔 calculate method에 크기가 9인 배열을 생성해서 for문을 이용해서 단수별로 1부터 9까지 곱한 값을 배열에 저장한 후 return하게끔 작성했다.
5번에서는 각 단마다 for문으로 출력 코드를 일일히 작성했었는데 print method를 만들어서 각 단마다 print(result) 한줄로 끝내게끔 했다.
마지막으로 각 단마다 calculate(구구단수)와 print(result)를 작성한 것을 for문으로 묶었다.
//7번 코드를 이용.
public class Gugudan {
public static int[] calculate(int times) {
int[] result = new int[9]
for (int i=0; i<result.length; i++) {
result[i] = times * (i + 1);
}
return result;
}
public static void print(int result) {
for (int i=0; i<result.length; i++) {
System.out.println(result[i]);
}
}
public class GugudanMain {
public static void main(String[] args) {
for (int i=2; i<10; i++) {
int[] result = calculate(i);
print(result)
}
}
}
클래스란 객체를 정의하는 틀 또는 설계도를 의미한다. 실제 현업에서 프로젝트를 진행하면 코드가 몇만줄씩 된다고 한다. 그렇게 긴 코드를 한 파일에 저장하게 되면 여러모로 비효율적일 것이다. 코드를 돌리는데도 오래 걸릴 것이고, 유지, 보수하는데도 불편함이 있을 것이다. 그래서 여러 분류 기준을 두어 클래스를 나누어서 따로 파일을 형성해 놓는다고 한다. 여기 구구단 코드에서는 프로그램을 시작하는 역할을 하는 main method와 구구단을 구현하는 데 필요한 method 로 나누어 2개의 클래스에 각각 저장해 놓았다.
메소드, 클래스, 패키지 순으로 더 큰 범위이다. 클래스 이름을 지을 때는 대문자로 시작하고, 메소드 이름은 소문자로 시작하는게 약속이다. 패키지는 대형차, 소형차와 같은 차종, 클래스는 소나타, 그랜저와 같은 차량, 메소드는 엔진, 휠과 같은 부품으로 비유할 수 있을 것이다.
(3),(4)는 실제로 코드를 돌렸을때 떴던 오류들이다. 근데 좀 답답한건 왜 떴는지도 모르겠고, 이것 저것 만지다 되긴 됐는데 왜 됐는지도 모르겠다.
사진의 빨간 박스가 처음에는 원래 파일인 Gugudan으로 되어 있었는데 main method가 있는 GugudanMain으로 바꾸고 돌렸더니 정상적으로 작동했다. 더 공부해보고 따로 포스팅해야겠다.
(ctrl + shift + F10 단축키가 뭔지도 알아보기)