뭉지(moonz)
작은 발자국들의 위대한 여정
뭉지(moonz)
  • All (200)
    • Test Code (4)
    • 백엔드 개발하며 작성한 (25)
      • Spring (16)
      • 데이터베이스 (6)
      • 기억할 내용 (3)
    • 언어 (53)
      • Java (25)
      • node.js (7)
      • Python (21)
    • 클라우드 (6)
    • Algorithm & Data Structure (51)
      • 개념 (15)
      • 문제 풀이 (36)
    • 유용한 모든 것 (16)
    • monologue (7)
      • 업무 노트 (1)
      • 관리 로그 (0)
      • 내 이야기 공책 (6)
    • Project (2)
    • TroubleShooting (8)
    • 지식 (18)
      • Machine Learning (6)
      • Review (7)
      • Web (5)
    • Computer Science (5)

블로그 메뉴

  • 홈
  • 태그

인기 글

최근 글

최근 댓글

전체 방문자
오늘
어제

티스토리

hELLO · Designed By 정상우.
뭉지(moonz)

작은 발자국들의 위대한 여정

언어/Java

기초실습 #2. 학생 점수 프로그램, 차량 관리 프로그램

2020. 8. 16. 22:18
반응형

프로그램 예제 풀기

1. 학생 점수 프로그램

2. 차량 관리 프로그램

 

# 학생 점수 프로그램

Q. 학생수와 각 학생들의 점수를 입력 받아 최고 점수 및 평균점수를 구하는 프로그램을 동작되는 예제를 보고 완성하시오. <배열문제>

<background>

- 학생 수를 입력받기 전까지 배열의 길이를 정할 수 없으므로 runtime때 지정하도록 함.

배열의 레퍼런스변수(참조변수) 선언.

- 4. 분석 에서는 최댓값과 평균값 구하기.

학생 점수 프로그램 코드 Q18.java 

public class Q18 {
	static Scanner scanner = new Scanner(System.in);	//왜 Scanner 객체 선언할때 static을 붙여야하지?

	public static void main(String[] args) {
		boolean run = true;		//반복문 실행할때  쓰일 boolean 변수
		int studentNum=0;		//학생 수
		int[] scores = null;	//배열의 레퍼런스변수 선언 (1)
				
		while(run) {	
        	System.out.println("-------------------------------------------");
			System.out.println("1.학생 수 | 2.점수입력 |  3.점수리스트 |  4.분석  | 5.종료");	
			System.out.println("-------------------------------------------");
			System.out.println("선택> ");
			int selectNo = scanner.nextInt();
			if (selectNo == 1) {
				System.out.println("학생수> ");
				studentNum = scanner.nextInt(); 	//동적할당은 runtime(프로그램 동작 중에) 때 할당 가능.
				scores = new int[studentNum];		//입력된 학생 수만큼의 integer 배열 길이 지정.
				//java배열은 만들고나면 수정이 불가능하지만, runtime때는 수정 가능.
			}
			//점수입력
			else if (selectNo ==2 ) {
				for (int i=0;i<scores.length;i++) {
					System.out.println("scores["+i+"]> ");
					scores[i]= scanner.nextInt();	//배열 인덱스 별 점수 넣어주기.
				}
			}
			//점수리스트
			else if (selectNo ==3) {
//				for (int i:scores)	: for each문은 배열반복문일때 사용
				for (int i=0;i<scores.length;i++) {			//for은 사실상 메서드이기때문에 결국 메서드 오버로딩.
					System.out.println("scores["+i+"]: "+scores[i]);	//배열에 들어있는 점수를 배열인덱스와 함께 출력. ex)scores[1]: 88
				}
			}
			//분석
			else if (selectNo ==4) {
				int max=0;	
				//처음에 넣을때부터 max를 비교하면서 정해놓고싶으면 기준값을 정해. "최소/최대값의 초깃값 규칙" >첫번째 데이터를 기준값으로.
				//But, 따로 메서드에서 최댓값을 구하는 것이기 때문에, 가장 작은 값의 변수로 초기화하고, 배열의 값들과 비교하여 최댓값 구함.
				int sum=0;
				double avg = 0;
				for(int i=0;i<scores.length;i++) {
					max = (max<scores[i])? scores[i] : max;	//삼항연산자 (1)
					sum += scores[i];		//평균 구하기 위해 모든 점수 합치는 변수 sum
				}
				avg = (double) sum / studentNum;	//sum을 학생수로 나누면 평균값. (double)로 형전환 해줘야 값이 소수점까지 나옴.
				System.out.println("최고 점수: "+max);
				System.out.println("평균 점수: "+avg);
				
			}
			else if (selectNo ==5) {	//run=false되면 while문 종료.
				run = false;
			}
		}
	}
}

(1) 참조변수 생성

int[] scores = null;

scores = new int[studentNum]; 

항상 한 줄로 배열이 생성됐는데 이걸 두 줄로 나눠놓으니 헷갈리기 시작해서 다시 알아보았다.

우선, 객체의 참조변수를 선언할 때를 봐보면 먼저, 메모리를 생성하고 그값(참조값)을 변수에 넣어 참조변수를 생성하는 것이다.

위 코드처럼 배열이 아닌 그냥 참조변수 생성을 나눠서 보면Q18 q = null;    //메모리가 생성되기 전, null로 초기화.q = new Q18();  //연산자 new와 생성자를 이용해서 특정 메모리 생성. 그 메모리의 (주소 매핑하는)참조값이 q에 할당됨.이처럼 int[] scores 도 똑같다. 1. integer형인 배열의 변수가 null로 초기화되었고,2. studentNum 길이의 메모리를 생성하여 변수에 할당해줬으므로 레퍼런스변수(참조변수)가 된것이다.

 

**참조값 != 주소값C++ 언어에서는 new를 이용해서 메모리를 생성하면 주소 그 자체를 직접 넘겨주어 포인터변수를 이용해서 주소를 사용자가 직접 관리하는 반면,Java 에서는 메모리 주소를 바로 주지 않고, 인스턴스의 메모리 주소 대신 참조값을 할당해주는 것이다.

 

(2) 삼항연산자 (조건)? (참값):(거짓값);
ifelse문 기능과 동일하여, 값을 찾을 때 쓰이는 연산자.
조건이 맞으면 왼쪽값(참값)을 변수에 넣고, 거짓이면, 오른쪽 값(거짓값)을 변수에 저장한다.

 

 

# 차량 관리 프로그램

Q. 차량 관리 프로그램을 만드시오.

예시

#### 자동차 정보 프로그램 ####
1. 자동차 정보 입력
2. 저장된 목록 보기
3. 각 자동차의 구매 가격 조회
4. 옵션이 있는 자동차 정보 조회
5. 빠른 자동차와 느린 자동차의 속도차 조회
6. 프로그램 이용 종료
##########################
입력 :

<background>

max와 min 객체를 어디에 선언해야될지 생각하기.

 

차량 관리 프로그램 코드 Car.java

class save_data {				//private으로 선언하여 접근할때는 get메서드 이용해서 접근 가능!
	private String carName;		//자동차이름
	private int enginPrice;		//엔진가격
	private int tirePrice;		//타이어가격
	private String option;		//옵션
	private String optionName;	//옵션이름
	private int maxSpeed;		//최고속도
	private int price;			//총가격(엔진+타이어가격)
/*(1)
	public int max;
	public int min=10000;
*/
	//매개변수 있는 생성자. 변수 값 설정 가능.
	public save_data (String carName, int enginPrice, int tirePrice, String option, String optionName, int maxSpeed, int price) {
		this.carName = carName;
		this.enginPrice = enginPrice;
		this.tirePrice = tirePrice;
		this.option = option;
		this.optionName = optionName;
		this.maxSpeed = maxSpeed;
		this.price = price;
	}
	
	//프로그래밍이 돌아가면서 값을 갱신하게 되면 set이 필요하지만 지금은 갱신할 일 없으니까 set메서드는 안써도되.
	public String getName() { return carName; }			
	public int getenginPrice() {return enginPrice; }
	public int gettirePrice() { return tirePrice; }
	public String getOption() { return option; }
	public String getoptionName() { return optionName; }
	public int getmaxSpeed() {return maxSpeed; }
	public int getPrice() {return price; }
	
/* (2)
	public void setName(String carName) { this.carName = carName; }
	public void setenginPrice(int enginPrice) {this.enginPrice = enginPrice; }
	public void settirePrice(int tirePrice) { this.tirePrice=tirePrice; }
	public void setOption(String option) {this.option= option; }
	public void setoptionName(String optionName) {this.optionName = optionName; }
	public void setmaxSpeed(int maxSpeed) { this.maxSpeed= maxSpeed; }
	public void setPrice(int price) {this.price = price; }
*/
}

public class Car {
	private static save_data[] carArray = new save_data[100];	//자동차정보 객체들을 한 배열인덱스에 저장할 예정.
	private static Scanner scanner= new Scanner(System.in);	//static은 메서드가 끝나도 계속 유지됨.
	private static int car_num=0;	//자동차가 기록돼있는 것까지만 출력하려고 자동차갯수 입력되는 변수.
	private static int max_s=-1;	//밖에다 선언하면 객체랑 객체끼리 부딪쳐. ??? (1)
	private static int min_s=1000;	//최댓값, 최소값의 초깃값은 각각 가장 작은 값과 큰 값을 저장해야함.
	
	//(3) main안에 있는 프로그램 목록 출력 코드와 ifelse를 따로 메서드로 만드는 것도 괜찮음.
	public static void main(String[] args) {
		
		boolean run = true;		//true일때까지 while문 반복
		while (run) {
			System.out.println("#### 자동차 정보 프로그램 ####");
			System.out.println("1. 자동차 정보 입력 \n2. 저장된 목록 보기\n3. 각 자동차의 구매 가격 조회\n4. 옵션이 있는 자동차 정보 조회\n5. 빠른 자동차와 느린 자동차의 속도차 조회\n6.프로그램 이용 종료");
			System.out.println("########################");
			System.out.println("입력: ");
			int selectNo = scanner.nextInt();
			
			if(selectNo == 1) { createCar();}	//1. 자동차 생성
			else if(selectNo == 2) { carList();	}	//2. 자동차 목록 보기
			else if(selectNo ==3) { carPrice(); }	//3. 자동차 구매가격 조회
			else if(selectNo ==4) { optionCarList(); }	//4. 옵션있는 자동차 조회
			else if(selectNo ==5) { maxminSpeeddiff(); }	//5.속도의 최댓값최소값 구하기
			else if(selectNo ==6) {		//6. run=false; 반복문 종료
				System.out.println("프로그램 종료");
				run = false;
			}
		}
	}
	//자동차 생성하기
	static public void createCar() {
		scanner.nextLine();	//(4)
		System.out.println("----------------");
		System.out.println("1. 자동차 정보 입력");
		System.out.println("----------------");
		System.out.print("이름: "); String carName = scanner.nextLine();		//각각 자동차 정보를 객체에 저장.
		//private이어서 접근못하는 carName에 어떻게 여기선 접근해서 설정하지?
		System.out.print("엔진 가격: "); int enginPrice = scanner.nextInt();
		scanner.nextLine();
		System.out.print("타이어 가격: "); int tirePrice = scanner.nextInt();
		scanner.nextLine();		
		System.out.println("옵션유무 입력 (있음/없음): "); String option = scanner.nextLine();	
		String optionName;
		if( option.equals("없음"))	//옵션유무가 없으면
			optionName = "없음";		//옵션이름에도 "없음"을 저장.
		else		//옵션유무가 있으면
			System.out.print("옵션 이름: "); optionName = scanner.nextLine();	//옵션이름 입력.
		
		System.out.print("최고속도: "); int maxSpeed = scanner.nextInt();
		scanner.nextLine();

		max_s= (maxSpeed>max_s) ? maxSpeed : max_s;	//입력한 최고속도가 최대값인지 그때그때 바로 비교해서 max_s에 저장.
		min_s= (maxSpeed<min_s) ? maxSpeed : min_s;	//입력한 최고속도가 최솟값인지 그때그때 바로 비교해서 min_s에 저장.
		
		int price = enginPrice+tirePrice;			//가격은 엔진+타이어 가격.
		System.out.println("구매 가격: "+price);
		save_data newCar = new save_data(carName, enginPrice, tirePrice, option, optionName,maxSpeed,price);		
		//자동차 정보를 다 객체에 입력했으면, 그것을 생성자를 이용해서 초기화 시켜준후 한 객체에 입력. newCar는 한 자동차의 정보가 모두 담겨있는 객체.
		//(5)
		carArray[car_num] = newCar;		//처음엔 0이니까 배열 인덱스 0부터 차곡차곡 자동차정보가 저장됨
		car_num+=1;		//다음 인덱스에 다른 자동차정보가 저장될 것을 생각하여 +1 해놓기.
        System.out.println("자동차 정보가 등록되었습니다.");
	}
	//자동차목록보기
	static public void carList() {
		System.out.println("----------------");
		System.out.println("2. 자동차 목록 보기");
		System.out.println("----------------");
		if (car_num<=0) {	//car_num을 이용해서 0이하이면 등록된 차가 없으므로 반복문실행하지 않아도 되니까 먼저 확인하기.
			System.out.println("등록된 차량이 없습니다.");
			return;		//메서드 종료.
		}
		for (int i=0;i<carArray.length;i++) {
			save_data account = carArray[i];		//배열의 한 인덱스 정보를 객체에 저장.
			if (account != null) {			//객체가 비어있지 않으면 자동차 정보를 출력하는데, get()메서드로 각 객체에 접근하여 출력.
				System.out.println("이름: "+account.getName());
				System.out.println("엔진 가격: "+account.getenginPrice());
				System.out.print("타이어 가격: "+account.gettirePrice());
				System.out.println("옵션: "+account.getOption());
				System.out.println("옵션 이름 : "+account.getoptionName());
				System.out.println("최고속도: "+account.getmaxSpeed());
				System.out.println("구매 가격: "+account.getPrice());
			}
		}
	}
	//구매가격 조회
	static public void carPrice() {
		System.out.println("----------------------");
		System.out.println("3. 각 자동차의 구매가격 조회");
		System.out.println("----------------------");
		if (car_num<=0) {		//마찬가지로 등록된 자동차가 없으면
			System.out.println("등록 된 차량이 없습니다.");	
			return;		//메서드 종료.
		}
		for (int i=0;i<carArray.length;i++) {
			save_data car_data = carArray[i];	//각 배열의 인덱스 정보를 객체에 저장.
			if ( car_data != null)		//객체가 비어있지 않으면 (자동차 정보가 있으면)
				System.out.println(car_data.getName()+": "+car_data.getPrice());	//자동차 이름과 가격 출력.
		}
	}
	//옵션이 있는 자동차 조회
	private static void optionCarList() {
		System.out.println("----------------------");
		System.out.println("4. 옵션이 있는 자동차 조회");
		System.out.println("----------------------");
		if (car_num<=0) {		//차량 개수가 0개 이하이면
			System.out.println("등록 된 차량이 없습니다.");
			return;
		}
		for (int i=0;i<carArray.length;i++) {
			save_data car_data = carArray[i];
			if ( car_data.getOption() =="있음") {		//option이 있으면 자동차 정보 조회.
				System.out.println("이름: "+car_data.getName());
				System.out.println("엔진 가격: "+car_data.getenginPrice());
				System.out.print("타이어 가격: "+car_data.gettirePrice());
				System.out.println("옵션: "+car_data.getOption());
				System.out.println("옵션 이름 : "+car_data.getoptionName());
				System.out.println("최고속도: "+car_data.getmaxSpeed());
				System.out.println("구매 가격: "+car_data.getPrice());
			}
		}
	}

	//빠른 자동차와 느린 자동차의 속도차 조회
	private static void maxminSpeeddiff() {
		if(car_num <2) {		//1대만 등록되면 빠른/느린 자동차 비교가 안되니까 2대이상은 있어야해.
			System.out.println("차량이 2대이상 등록되지 않았습니다.");	
			return;
		}
		System.out.println("-------------------------------");
		System.out.println("5. 빠른 자동차와 느린 자동차의 속도차 조회");
		System.out.println("-------------------------------");
		System.out.println("빠른 자동차와 느린 자동차의 속도차: "+(max_s-min_s));	//두 변수의 차이.
	}
}

중요하면서 헷갈린 부분은 번호 표시!

(1) max_s와 min_s를 어디 메서드 안에 선언해주는게 맞을까?

 

사실 처음에 save_data 메서드 안에 선언했었다. 그런데 

// public int max_s;
// public int min=10000;

 

(2) Q. set()메서드를 선언해주지 않아도 되는 이유는?

프로그래밍이 돌아갈때 객체 값을 갱신하게 되면 set() 메서드가 필요하지만 갱신할 필요 없으니까 set()메서드는 필요없어서 선언해주지 않아도 된다.

//자동차 등록할때 객체들 값을 지정할때 생성자()로 접근하여 지정하니까!

그럼 set을 쓸땐 어떤 경우지?

 

(3) 선생님은 main을 세줄로 만들고 따로

메뉴 보여주는 여러 줄의 print문을 print_UI() 메서드로,

메뉴선택하는 if-else문을 boolean 타입 mode()메서드로 만들어주었다. 

+ifelse대신 switch-case문으로 했고, 

더보기

print_UI()와 mode()

	static public void print_UI() {
		System.out.println();
		System.out.println("########### 자동차 정보 프로그램 ###########");
		System.out.println(" 1. 자동차 정보 입력");
		System.out.println(" 2. 저장된 목록 보기");
		System.out.println(" 3. 각 자동차의 구매 가격 조회");
		System.out.println(" 4. 옵션이 있는 자동차 정보 조회");
		System.out.println(" 5. 빠른 자동차와 느린 자동차의 속도 차 조회");
		System.out.println(" 6. 프로그램 이용 종료");
		System.out.println("############################################");
		System.out.print("입력:");
	}
	
	static public boolean mode() {
		print_UI();
		int in=scanner.nextInt();
		switch (in) {
		case 1:
			enter();
			return true;
		case 2:
			view();
			return true;
		case 3:
			search_P();
			return true;
		case 4:
			search_Op();
			return true;
		case 5:
			speed_C();
			return true;
		case 6:
			System.out.println("프로그램이 종료됩니다.");
			return false;
		default:
			System.out.println("잘못 입력 하셧습니다.\n 다시 입력해주세요.");
			return true;
		}
	}

(4)

int price = scanner.nextInt();   //1

scanner.nextLine();                //2String name = scanner.nextLine();   //3

Q. 중간에 scanner.nextLine(); 을 써주는 이유?

A. 첫번째 int만 입력받고 그다음 3번째 라인을 건너띄는 경우가 발생하는데, 이는 nextInt()에서 Enter를 칠때 발생하는 '개행문자'를 처리하지 않고 버퍼에 남기기 때문에 개행문자를 중간에 넣어줘야한다. 그 방법 중 하나로,1번과 2번 사이에 scanner.nextLint();을 넣어주는 것이다.

 

+하나 더 알게 된 것이 String 변수에 scanner입력을 받을 때 next()를 써왔는데 nextLine()이 더 정확하다는 것이다.

이유는, 

next() : 문자 또는 문자열을 공백을 기준으로 한단어 또는 한문자씩 입력 받는다.

nextLine() : 문자 또는 문장 한 라인 전체를 입력받는다.

ex) Hello java 를 입력을 하게 되면, next()는 Hello를, nextLine()은 Hello java를 변수에 넣어주게 된다.

 

(5) 사실 처음 썼던 코드는 저 두줄이 아니라, 반복문이었다.

for (int i=0; i<carArray.length;i++) {

   if (carArray[i] == null) {

      carArray[i] = newCar;

      System.out.println("자동차 정보가 등록되었습니다.");

      break;

   }

}

이렇게 해도 작동은 하지만, 등록된 자동차의 갯수 변수(car_num)를 하나 선언해서, 하나씩 자동차가 하나씩 추가될 때마다 그 변수를 1씩 올려주어(car_num+=1;) 배열에 자동차정보를 담는 코드로 쓰는게 훨씬 코드줄이 줄어든다는 것을 알게됐음!

 

반응형
저작자표시 (새창열림)

'언어 > Java' 카테고리의 다른 글

기초 #5. 추상클래스 (ex. 계산기 프로그램)  (0) 2020.08.22
기초 #4. 상속과 다형성  (0) 2020.08.21
기초실습 #1. 계좌이체 프로그램 예제  (0) 2020.08.14
기초 #3 변수  (0) 2019.06.28
기초 #2 이클립스 실행하기  (0) 2019.06.28
    '언어/Java' 카테고리의 다른 글
    • 기초 #5. 추상클래스 (ex. 계산기 프로그램)
    • 기초 #4. 상속과 다형성
    • 기초실습 #1. 계좌이체 프로그램 예제
    • 기초 #3 변수
    뭉지(moonz)
    뭉지(moonz)
    제가 깨달은 것을 정리하는 공간입니다. 🧡

    티스토리툴바