함수
- 함수
'하나의 기능을 수행하는 일련의 코드' 이다.
예를 들어 여러 코드에서 '더한다'라는 행위를 반복적으로 하고 있으면 '더한다' 라는 기능을 수행하는 코드를 묶어서
'더하기' 함수로 만들 수 있다.
그리고 더하기 기능이 필요할 때마다 이 함수를 불러서 연산을 하는 것이다.
이처럼 함수는 어떤 기능을 수행하도록 미리 구현해 놓고 필요할 때마다 호출하여 사용할 수 있다.
함수에 이름을 붙일 때는 의미를 알 수 있는 단어를 사용하는 것이 좋다.
- 함수 예시
'더하기' 함수를 만든다고 한다면 의미를 알도록 add라고 이름을 짓는다.
그리고 더할 두 수는 각각 num1, num2라고 정한다.
여기서 num1, num2 같이 함수의 입력으로 받는 변수를 '매개변수'라고 한다.
그리고 두 수를 더한 결과 값을 result 변수에 저장하여 돌려준다.
이를 '결과를 반환한다' 고 하며 이렇게 함수를 수행한 후 결과로 되돌려 주는 값인 result를 '반환 값' 이라고 한다.
int add(int num1, int num2){
int result;
result = num1 + num2;
return result;
}
더하기 함수가 하는 일을 실제 코드로 작성해 본 것이다.
이렇게 함수가 하는 일을 코드로 구현하는 것을 '함수를 정의한다' 라고 한다.
- 매개변수 없는 경우
함수에 따라서 매개변수가 필요 없는 경우도 있다.
즉 전달 받아야할 값이 필요 없다는 것인데 그런 경우는 함수 내부의 기능이 전달할 값이 필요 하지 않을 경우이다.
1부터 10까지 더한 값을 반환하는 하며 매개변수가 필요없는 함수 예시
int getTenTotal(){
int i;
int total = 0;
for(i = 1; i <= 10; i++){
total += 1;
}
return total; //1부터 10까지 더한 값을 반환
}
- return 예약어와 반환형
함수 예시의 add() 함수를 수행한 후 결과 값은 변수 result에 저장된다.
result에 저장된 결과 값은 함수를 호출했을 때 반환 되는 값이므로 '반환 값' 이라고도 부른다.
'이 함수의 결과 값을 반환한다' 라는 뜻하는 예약어가 바로 return이다.
반환 값의 자료형을 반환형이라고 하는데 add() 함수에서 반환형은 정수형이므로 'int' add()라고 함수 선언을 했었다.
- 반환 값이 없는 함수 예시
void printGreeting(String name) {
System.out.println(name + "님 안녕하세요");
return; //반환 값 없음
}
반환형을 쓰는 위치를 비워 두면 오류가 나기 때문에 void를 사용한다.
void는 비어 있다는 의미로 '반환할 값이 없다'는 뜻의 예약어이다.
- 함수 수행을 끝내고 프로그램 흐름 중에서 호출한 곳으로 다시 되돌아갈 때 사용하는 return
void divide(int num1, int num2){
if(num2 == 0){
System.out.println("나누는 수는 0이 될 수 없습니다.");
return; // 함수 수행 종료
}
else {
int result = num1 / num2;
System.out.println("num1" + "/" + "=" + result + "입니다.");
}
}
위 함수는 두 수를 매개변수로 전달받아서 나눗셈을 한 후 몫을 출력하는 함수이다.
만약 나누는 수가 0이라면 당연히 수행하면 안되기 때문에 함수 수행을 종료하는 예약어 return 함수를 사용한다.
함수 수행을 종료하는 목적이기에 변환 값을 적지 않아도 된다.
- 함수 호출하고 값 반환하기
함수를 사용하는 것을 '함수를 호출한다'라고 한다.
public class FunctionTest {
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
int sum = add(num1, num2);
System.out.println(num1 + " + " + num2 + " = " + sum + "입니다.");
}
public static int add(int n1, int n2){
int result = n1 + n2;
return result;
}
}
add() 함수를 구현했다.
add() 함수는 두 개의 매개변수에 int형 값을 전달받아 두 수의 합을 돌려준다.
결과 값이 정수이기 때문에 변환형이 int형이다.
함수를 호출하는 코드는 int sum = add(num1, num2) 부분이다.
반환 값이 int형 이기 때문에 결과 값이 저장되는 sum 변수를 int로 선언한다.
- 매개변수에 대하여
add() 함수를 호출할 때 num1, num2 두개의 변수를 넘겼다.
그리고 함수를 구현하는 부분에서는 add(int n1, int n2)와 같이 n1, n2를 사용했다.
함수를 호출할 때 넘겨주는 변수 명과 함수를 구현할 때 사용한 매개변수 이름은 같지 않아도 된다.
이유는 num1, num2는 main() 함수의 변수이기 때문이다.
add(num1, num2)로 사용하면 add()함수에 두 값을 넘겨 줄 수 있고 매개변수 n1, n2는 실제 함수로 넘어온 두 값을 받아주는 역할이다.
다시 말해 n1, n2는 add() 함수에서 선언한 새로운 변수이다.
따라서 함수를 호출할 때 사용하는 변수 명과 호출되는 함수에서 사용하는 변수는 서로 다른 변수이므로 이름이 같아도 되고 달라도 된다.
밑의 내용을 보면 더 이해가 된다.
함수 호출과 스택 메모리
함수를 호출하면 그 함수만을 위한 메모리 공간이 할당 되는데 이 메모리 공간이 스택(stack)이다.
스택은 마지막에 추가된 자료부터 순서대로 꺼내서 사용할 수 있으며 LIFO(Last In First Out) 구조라고 부른다.

함수가 호출되면 그 함수가 사용할 메모리 공간이 스택에 생성된다.
프로그램을 시작할 때 main() 함수부터 호출하기 때문에 가장 먼저 main() 함수에 포함된 변수 num1, num2, sum을 저장할 메모리 공간이 생성된다.
그리고 main() 함수에서 add() 함수를 호출하면 add() 함수를 저장할 메모리 공간이 스택에 새롭게 생성된다.
- add() 함수 수행이 끝나고 함수에 할당했던 메모리 공간을 해제하는 과정

add() 함수 수행이 끝나고 결과 값이 반환되면 add() 함수가 사용하던 메모리 공간은 자동으로 사라진다.
프로그램에서 여러 함수를 사용하는 경우에 함수를 호출한 순서대로 메모리 공간이 만들어지고 맨 마지막에 호출한 함수부터 반환된다.
따라서 메모리 공간도 맨 마지막에 추가된 것부터 스택에서 사라진다.
즉 A() - B() - C() 함수의 순서로 호출했다면 C() - B() - A() 순서로 반환되고 스택 메모리도 이 순서대로 소멸한다.
- 지역변수 및 매개변수 명이 달라도 되는 이유
main() 함수에서 사용하면 num1, num2 변수와 add() 함수에서 사용하는 n1, n2 변수는 서로 다른 메모리 공간을 사용하므로 이름이 같든 다르든 상관없다.
이렇게 함수 내부에서만 사용하는 변수를 지역 변수라고 한다.
지역 변수는 스택메모리에 생성된다.
함수의 장점
1. 함수를 사용하면 기능을 나누어 코드를 효율적으로 구현할 수 있다.
예시로 계산기를 구현하려면 숫자를 입력 받아야하고 사칙 연산을 한 후 결과 값을 출력한다.
이 과정을 구현하는 코드를 main() 함수 안에 한꺼번에 작성할 수도 있지만 덧셈, 뺄셈, 곱셈, 나눗셈으로 기능을 나누어 각 연산을 수행하는 함수를 여러 개 만든 후 main() 함수에서 필요할 때마다 각 함수를 호출할 수 있다.
이렇게 기능을 분리해서 구현하면 프로그램 코드의 가독성이 좋아진다.
2. 기능별로 함수를 구현해 놓으면 같은 기능을 매번 코드로 만들지 않고 그 기능의 함수를 호출하면되며 중복된 코드를 막을 수도 있다.
3. 프로그램을 실행할 때 생긴 오류를 수정하는 디버깅 작업을 할 때 편리하다.
하나의 기능이 하나의 함수로 구현되어 있기 때문에 오류가 난 기능만 찾아서 수정하면 되기 때문이다.
하나의 함수에 하나의 기능을 구현하자
위에서 우리는 더하기 연산을 위해 add() 함수를 만들었다.
이 함수가 해야할일은 '더하기'이다.
만약 하나의 함수에 여러 기능이 섞여 있으면 위에서 말한 함수의 장점을 활용할 수 없다.
무조건 소스 코드를 나누어 호출한다고 해서 함수를 구현하는 것이 아니다.
필요한 기능 함수를 만들고, 그 이름에 맞는 하나의 기능을 구현하는 것이 중요하다.
클래스 기능을 구현하는 메서드
자바 프로그램에는 클래스 내부에서 사용하는 멤버 함수가 있는데 이를 메서드(method)라고 한다.
메서드는 멤버 변수를 사용하여 클래스의 기능을 구현한다.
즉 메서드는 함수에 객체 지향 개념이 포함된 용어로 이해하면 된다.
함수의 스택 메모리 사용 방법과 함수의 장점 등도 모두 메서드에 동일하게 적용된다.
- 메서드 구현
public class Student {
int studentID;
String studentName;
int grade;
String address;
public String getStudentName(){
return studentName;
}
}
메서드 이름은 해당 클래스를 사용하는 코드의 입장에서 짓는 것이 좋다.
Student 클래스를 사용하는 A 클래스가 있다고 하면 A클래스에서 학생 이름(studentName)을 가져오는(get) 기능을 제공하는 메서드 이름은 getStudentName으로 짓는다.
이 메서드의 반환 값은 studentName 인데 studentName 자료형이 String이므로 반환형도 String이다.
- 학생 이름을 멤버 변수에 대입하는 메서드
public class Student {
int studentID;
String studentName;
int grade;
String address;
public String getStudentName(){
return studentName;
}
public void setStudentName(String name){
studentName = name;
}
}
setStudentName() 메서드는 Student 클래스를 사용하는 다른 코드에서 학생 이름을 새로 지정하거나 바꾸어 준다.
studentName 값을 지정하는(set) 기능을 제공하는 것이다.
이 메서드는 이름을 전달받아 지정하는 것이기 때문에 매개변수 name이 필요하다.
매개변수 name을 멤버 변수 studentName에 대입하면 학생 이름이 지정된다.
반환 값은 없으므로 반환형은 void로 지정한다.
'JAVA' 카테고리의 다른 글
| 생성자 (0) | 2024.12.13 |
|---|---|
| 클래스와 인스턴스 (0) | 2024.12.12 |
| 객체 지향 프로그래밍, 클래스 (1) | 2024.12.11 |
| continue문, break문 (0) | 2024.12.10 |
| 반복문 (0) | 2024.12.09 |