Back-End

[JAVA] 기초 공부 6(함수)

Minch13r 2025. 1. 7. 11:46

2025.1.7 오늘은 자바의 함수 공부

 

상속과 함수는 다르다

예시를 들자면 상속은 이브이가 쥬피썬더(?) 뭐 하여튼 진화하는거를 상속이라고 하고 함수는 꼬부기 몸통박치기, 피카츄 몸통박치기 등 여러 포켓몬이 몸통박치기를 쓴다고 했을 때 같은거를 몸통박치기 = 박 이런식으로 줄여서 써보자 이런느낌인거임

 

[함수]

y = x + 2

f(x) = x + 2

 

함수의 3요소 => 메서드 시그니처(method signature)

1) input 입력값 인자 인수 매개변수 파라미터 args

2) output 출력값 결과값 return 리턴값 반환값

3) 기능 >> 함수명을 통해 유추 가능하게끔

ex) hello() println() main() equals() etc...

 

함수 설명하라고 할 때 간략하게 소개가 가능해야 한다. 예를 들자면 int로 정수값 두 개 받고 평균이랑 합계 내는 그런 함수다 이런식으로 설명.

 

실제로 없는거지만 학습을 위해 임의로 만든 4유형임. 이 4개의 유형들은 각자 다른 경우에 보여주는 함수들을 뜻한다.

1 유형 2 유형 3 유형 4 유형
input x input o input x input o
output x output x output o output o

 

Ctrl + C, Ctrl + V를 할 경우 유지보수에 어려움을 겪고 함수를 하는 경우 유지보수에 용이하다

 

왜 유지보수에 어려움을 겪나면, 똑같은 코드가 여기저기에 위치할 때 한 번에 바꾸지 못하고 여러번에 걸쳐서 바꿔야 하기 때문이다. 또 어떤 경우에는 코드를 지나쳐 못 바꾸는 경우도 생기기 때문이다.

 

유지보수에 용이한 코드는 중복이 없는 코드를 의미한다.

또한 코드를 재사용하기에 용이, 개발 시간 단축, 개발 비용 절감, 오류의 파급효과가 줄어든다.

 

함수화는 모듈화, 컴포넌트화, 고도화, 성능최적화 등등 다양하게 불린다.

함수끼리는 {} 블록 코드가 절대 겹치지 않는다.


1유형 예시코드

package day008.class01;

public class Test01 {
    // 함수끼리는 {} 블록 코드가 겹치지 않는다.
    // 함수 선언, 정의
    public static void hello(){
        System.out.println("안녕하세요! ㅎㅎ");
    }

    // 1유형(input x, output x)   
    public static void printNum(){
        int num = 1234;
        System.out.println(num);
    }

    public static void main(String[] args) {
        // 함수를 호출한다.
        // 호출을 해야 함수 사용이 가능하다.
        hello();

        printNum();
    }
}

2유형(input o, output x)

package day008.class01;

public class Test02 {
    // 함수 선언, 정의
    public static void printNum(int num){
        num++;
        System.out.println("num = " + num);
    }
    public static void test(int a, int b){
        a += b;
        System.out.println("a = " + a);
    }

    public static void main(String[] args) {
        // 2유형(input o, output x)
        int num = 123;
        printNum(num); // 괄호 안에 값을 입력해야 출력 가능
        // 인자를 전달할 때 변수의 "값"만 전달
        // call by value 값에 의한 호출
        // 받아들이는 정보가 num 이라는 것이 아니라 123이라는 것만 받는 것
        // printNum 함수는 main함수 안에 있는 num 이라는 존재 자체를 모름
        System.out.println("최종 num = " + num);

        // 결과는 124, 123 순서로 출력됨
        // 맨처음에 123이 함수 printNum으로 넘어가고 num++를 통해 124로 저장
        // 이후 prinNum(num)을 통해 124출력
        // sout 최종 num은 main 함수 안에 있는 123이 출력됨(printNum 함수로 안 감)
        // main 함수와 printNum의 공간은 다름
        int a = 1;
        int b = 2;
        test(b, a);
        System.out.println("a, b = " + a + "," + b);
         // 각각 다른 함수에 위치하는 a와 b를 잘 확인하고 문제를 풀어야 함
       
    }
}

이해도 테스트

package day008.class02;

public class Test01 {
    public static void test01(){
        int a = 1;
        int b = 2;
        System.out.println("4 a= " + a);
        System.out.println("4 b= " + b);
    }

    public static void test02(int b, int a){
        System.out.println("5 a= " + a);
        System.out.println("5 b= " + b);
        a++;
        b++;
    }

    public static void test03(int a){
        System.out.println("6 a= " + a);
    }

    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        test01();
        System.out.println("1 a= " + a);
        System.out.println("1 b= " + b);
        test02(a,b); // a,b를 넣었지만 함수에서는 int b, int a임
        System.out.println("2 a= " + a);
        System.out.println("2 b= " + b);
        test03(a++);
        System.out.println("3 a= " + a);
        System.out.println("3 b= " + b);
    }
}

출력값


package day008.class02;
// 4유형(input o, output 0)
public class Test04 {
    public static boolean test(int a,int b) {
        if(a+b > 10) {
            return true;
        }
        else {
            return false;
        }
    }

    public static double makeAvg(int a,int b) {
        double avg=(a+b)/2.0;
        return avg;
    }

    public static void main(String[] args) {

        if(test(1,10)) {
            System.out.println("a+b는 10 초과입니다.");
        }
        else {
            System.out.println("아닙니다.");
        }

        double avg=makeAvg(1,10);
        System.out.println("1과 10 합의 평균은 "+avg+"입니다.");

    }
}

 

문제
결과값

리턴값에 a + b++ 이런식으로 하면 b = test04(b,b)라고 했기 때문에 test에 해당하는 함수도 출력되고 리턴 값이 main 함수에 있는 b에 저장되는 것이다.


package day008.class04;

import java.util.Random;

/*
* 다음의 요구사항을 수행하는 함수를 제작하시오.
* 또한, 그 함수가 제 몇 유형인지 작성하시오.
* */
public class Test01 {
    // 제 1 유형 input x output x
    // 1~10 사이의 랜덤정수를 화면에 출력하는 함수
    // 단순 출력이 대부분 1유형
    public static void test01(){
        Random rand = new Random();
        int num = rand.nextInt(10)+1;
        System.out.println(num);
    }

    // 제 2 유형 input o output x
    // main에서 num 정수를 입력받아와 홀수 짝수 여부를 출력
    // ~를 받아오는 input에 대한 힌트가 있음. 결과는 X(return 이런거)
    public static void test02(int num){
        if(num%2==1){
            System.out.println("홀수");
        } else {
            System.out.println("짝수");
        }
    }

    // 제 3 유형 input x output o
    // 1~10 사이의 랜덤정수를 main으로 반환하는 함수
    public static int test03(){
        Random rand = new Random();
        int num = rand.nextInt(10) + 1;
        return num;
    }

    // 제 4 유형 input o output o
    // main으로부터 정수값을 2개 입력받아와 더 큰 정수를 반환하는 함수
    // 단, 둘의 크기가 같다면 그 정수를 그대로 반환
    public static int test04(int a, int b){
        return a > b ? a : b;
    }

    public static void main(String[] args) {
        test01();

        test02(10);

        int num=test03();
        System.out.println(num);

        System.out.println(test04(1,20));
    }
}
package day008.class04;

import java.util.Scanner;

/*
1) 사용자가 입력하는 정수가 짝수라면 main으로 반환하는 함수.
   단, 입력한 정수가 짝수가 아니라면 다시 입력을 받는다.
2) 사용자가 입력하는 문자열을 화면에 출력하는 함수
3) main의 num 정수값을 입력받아 약수들을 출력하는 함수
4) 1~10사이의 랜덤정수를 main으로부터 2개 입력받아
   둘의 합이 홀수라면 T, 짝수라면 F를 반환하는 함수
*/
public class Test02 {
    // 함수1
    // 사용자가 입력하는 정수가 짝수라면 main으로 반환하는 함수.
    // 단, 입력한 정수가 짝수가 아니라면 다시 입력을 받는다.
    // input x, output o -> 3유형
    public static int test01(){
        Scanner sc = new Scanner(System.in);
        System.out.print("짝수를 입력하세요 : ");

        while(true) { // 무한루프, 반복횟수 불분명
            int num = sc.nextInt();
            if (num % 2 == 0) { // 나머지가 0인경우, 짝수
                System.out.println("짝수가 입력되었습니다.");
                return num; //main 함수의 num으로 반환
            }
            else { // 나머지가 1인 경우, 홀수
                System.out.print("짝수가 아닙니다. 다시 입력주세요 : ");
                continue; //가독성향상
            }
        }
        // 나는 return num을 안에 넣었지만 보편적인 경우에는 return num을 바깥으로 뺀다
        // return num 대신에 break;를 넣음
    }

    //함수2
    //사용자가 입력하는 문자열을 화면에 출력하는 함수
    // 1유형
    public static void test02(){
        Scanner sc = new Scanner(System.in); //스캐너 객체 생성
        System.out.print("문자열을 입력해주세요 : ");
        String ans = sc.next(); //문자열 입력받기
        System.out.println(ans); //문자열 출력
    }

    //함수3
    //main의 num 정수값을 입력받아 약수들을 출력하는 함수
    //input o, output x -> 2유형
    public static void test03(int num){
        int i = 1;
        System.out.print(num+"의 약수 : ");
        while(i<=num){ // i를 num까지 반복
            if(num % i == 0){ //8을 i로 나눴을 때 나머지가 0인 것
                System.out.print(i+" ");
            }
            i++;
        }
        System.out.println(); //줄바꿈
    }

    //함수4
    //1~10사이의 랜덤정수를 main으로부터 2개 입력받아
    //둘의 합이 홀수라면 T, 짝수라면 F를 반환하는 함수
    // input o, output o => 4유형
    public static boolean test04(int a, int b){
        if((a+b)%2 == 0){ //짝수인경우
            System.out.println("a+b는 " + (a+b) + "(으)로 짝수입니다.");
            return false;
        } else{ //홀수인경우
            System.out.println("a+b는 " + (a+b) + "(으)로 홀수입니다.");
            return true;
        }
    }

    public static void main(String[] args) {
        //함수 1 검증
        int num = 10;
        System.out.println("기본 num은 " + num + "입니다.");
        System.out.println("사용자가 입력하는 정수가 짝수라면 main으로 반환하는 함수");
        System.out.println("단, 입력한 정수가 짝수가 아니라면 다시 입력을 받는다.\n");
        num = test01();
        System.out.print("입력된 값 : " + num);
        System.out.println("\n====================");

        //함수 2 검증
        System.out.println("사용자가 입력하는 문자열을 화면에 출력하는 함수입니다.");

        test02();
        System.out.println("====================");

        //함수 3
        System.out.println("main의 num 정수값을 입력받아 약수들을 출력하는 함수\n");
        System.out.println("저장된 num값 : "+ num);
        test03(num);
        System.out.println("====================");

        //함수 4
        System.out.println("1~10 사이의 랜덤정수를 main으로부터 2개를 입력받았을 때");
        System.out.println("둘의 합이 홀수라면 T, 짝수라면 F를 반환하는 함수\n");
        Scanner sc = new Scanner(System.in);
        System.out.print("정수1을 입력하세요 : ");
        int a = sc.nextInt();
        System.out.print("정수2를 입력하세요 : ");
        int b = sc.nextInt();
        test04(a,b);
        System.out.println("====================");
    }
}

 

 

함수를 사용하면 결합도를 낮출 수 있다.

아래 코드는 지난 학생부 프로그램을 함수를 이용해 유지보수를 용이할 수 있게끔 만든 코드이다.

package day008.class05;

import java.util.Random;
import java.util.Scanner;

public class Test {
    public static void printMenu() { // 프로그램 ui
        System.out.println("=====학생부 프로그램=====");
        System.out.println("1. 전체 출력");
        System.out.println("2. 1등 출력");
        System.out.println("3. 정보 추가");
        System.out.println("4. 정보 변경");
        System.out.println("0. 프로그램 종료");
        System.out.println("=========================");
    }

    public static int inputAction(int MENU) {
        // 사용자에게 정수값을 올바르게 입력받아서
        // main()으로 전달 ===>> return

        Scanner sc=new Scanner(System.in);
        int action;
        while(true) {
            System.out.print("메뉴 정수로 입력 >> ");
            action=sc.nextInt();
            if(0<=action && action<=MENU) { // 결합도를 낮춤 ★
                break;
            }
            System.out.println("잘못된 번호입니다!");
        }
        return action;
    }

    public static int inputScore() {
        // 사용자에게 정수인 점수값을 올바르게 입력받아서
        // main()으로 전달 ===>> return

        Scanner sc=new Scanner(System.in);
        int score;
        while(true) {
            System.out.print("점수 정수로 입력 >> ");
            score=sc.nextInt();
            if(0<=score && score<=100) {
                break;
            }
            System.out.println("잘못된 점수입니다!");
        }
        return score;
    }

    public static int inputNum(int cnt) {
        Scanner sc=new Scanner(System.in);
        // 정보변경할 학생의 번호를 입력받음
        int num; // scope 이슈 해결
        while(true) { // 사용자로부터 "입력"을 받으면? 유효성 검사!
            System.out.print("정보변경할 학생의 번호 입력 >> ");
            num=sc.nextInt();
            if(1<=num && num<=cnt) { // 종료조건
                break;
            }
            System.out.println("해당 번호의 학생은 존재하지않습니다!");
        }
        return num;
    }

    // T,F?
    // 가졌니,없니?
    // ~~이니,아니니?
    public static boolean isEmpty(int cnt) {
        if(cnt<=0) {
            System.out.println("학생부에 저장한 데이터가 없습니다!");
            return true;
        }
        return false;
    }

    public static boolean isFull(int cnt,int[] list) { // ☆
        if(cnt>=list.length) {
            System.out.println("학생부에 저장공간이 부족합니다!");
            return true;
        }
        return false;
    }

    public static void printStuList(int cnt,int[] stuList) {
        // 현재 저장된 학생들의 점수정보를 출력
        for(int i=0;i<cnt;i++) { // stuList.length => 학생부 자체의 크기
            System.out.println((i+1)+"번 학생의 점수 : "+stuList[i]+"점");
        }
    }

    public static void printMaxScore(int cnt,int[] stuList) {
        // 학생부 배열에서 점수가 가장 큰 학생을 찾아서
        //  --->> 최대값 찾기 알고리즘
        int max=stuList[0];
        int maxIndex=0;
        for(int i=1;i<cnt;i++) { // ★
            if(max<stuList[i]) {
                max=stuList[i];
                maxIndex=i;
            }
        }

        // 출력
        System.out.println("1등은 "+(maxIndex+1)+"번 학생, "+max+"점입니다.");
    }

    public static void addStudent(int cnt,int[] stuList) {
        // 입력받은 점수 정보를 배열에 저장
        stuList[cnt]=inputScore();

        // 저장완료! 안내
        System.out.println("학생 정보 추가 완료!");
    }



    public static void main(String[] args) {
        final int MENU=4; // 제공가능한 메뉴의 번호

        int[] stuList=new int[3]; // 학생부
        int cnt=0; // 현재 학생부에 저장된 학생 수

        while(true) {
            printMenu();

            int action=inputAction(MENU);

            if(action==0) { // 종료조건
                break;
            }
            else if(action==1) { // 전체 출력
                if(isEmpty(cnt)) { // UI/UX
                    continue;
                }

                printStuList(cnt,stuList);
            }
            else if(action==2) { // 1등 출력
                if(isEmpty(cnt)) { // UI/UX
                    continue;
                }

                printMaxScore(cnt,stuList);
            }
            else if(action==3) { // 정보 추가
                if(isFull(cnt,stuList)) { // 최대학생수만큼 저장된 상황이라면
                    continue;
                }

                addStudent(cnt++,stuList); // ★
            }
            else if(action==4) { // 정보 변경
                if(isEmpty(cnt)) { // UI/UX
                    continue;
                }

                int num=inputNum(cnt);

             /*
             // 어떤 점수로 변경할지 결정
             // 랜덤으로 변경
             int score; // scope 이슈 해결
             while(true) {
                score=rand.nextInt(101); // 0~100
                if(score != stuList[num-1]) { // 점수가 이전과 다르면
                   break;
                }
             }
             stuList[num-1]=score;

             // 정보 변경 완료 안내
             System.out.println("학생 정보 변경 완료!");
             */
            }

        }


    }
}