프로그래밍언어/Go

함수『Tucker의 Go 언어 프로그래밍#7』

구구절절2 2021. 5. 16. 15:32
반응형

함수


ex.1

func Add(a int, b int) int {
				return a+b
}

하나하나 풀어쓰면 이런 뜻이다.

func : 함수 키워드 (함수를 이제부터 정의한다. )

Add : 함수의 이름을 뜻한다.

(a int , b int ) : 매개변수를 이름과 타입을 함께 적어준다. 컴마로 구분하고 여러개 받을 수 있다.

int : 반환값 (return값)

함수를 호출하면 생기는 일


함수는 중복 코드를 제거하는데 아주 유용하다. 그런 배경에서 탄생하기도 했다.

ex.1 에서 함수를 한번 정의하고 나면 함수를 정의하지 않고 사용할 수 있다.

package main 

import "fmt"

func Add(a int, b int) int {
				return a+b
}

func main() {
				c := Add(4,6)
				d := Add(6,7) 
				fmt.Println(c,d)
}

main 함수가 실행할 때 차례차례 한줄씩 컴퓨터가 명령을 읽는다.

이때 c := Add(4,6) 차례가 온다면 우선 현재 진행하고 있는 위치 (라인)을 저장한다.

함수는 스택 자료구조를 이용해서 값을 저장한다.

현재 진행중인 위치를 저장하고 매개변수 4,6을 저장한다.

그 후 Add()함수가 정의된 라인으로 이동한다.

스택 자료구조를 이용하기 때문에 6부터 다시 꺼내어 b에 6을 대입하고 a에는 4를 대입한다.

그리고 다시 돌아갈 라인을 기억하고 함수가 종료되고 반환값 (return값)이 나오면 다시 반환값10을 차례로 스택 메모리에 저장하고 (push) 다시 원래 위치로 돌아가 마지막 반환값부터 차례로 나오면서 Add(4,6) 은 10으로 대체된다. 따라서 c:=10 이 된다.

사소한 함수 사용법


  • 함수는 값을 여러개 반환할 수 있다. 반환값이 여러개일 때는 반환 타입들을 소괄호로 묶어서 표현한다.

package main

import "fmt"

func Divide(a,b int) (int,bool) { //매개변수 둘이 타입이 같으면 생략가능! 
	if b ==0 {
		return 0,false
	}
	return a / b , true
}

func main()  {
	//리턴값이 두개이기 때문에 변수도 두개가 필요 
	c,success := Divide(9,3) 
	fmt.Println(c,success)

	d,success := Divide(9,0)
	//success는 이미 변수선언을 했는데 왜 다시 변수 선언을 해줄까? 
	//사실 success를 다시 변수선언 한 것은 아님 
	//d가 변수선언이 안되어있기 때문에 둘중에 하나라도 변수선언이 안되어있다면 변수선언을 해줘야함

	fmt.Println(d,success)
	
}

  • 함수 선언부부터 반환 변수명을 적는 것이 가능하다.
func Divide(a,b int) (result int , success bool)  { //반환값을 처름부터 정한다. 
	if b ==0{
		result = 0 
		success = false
		return // 자동으로 result와 success가 반환된다. 
	}
	result = a / b 
	success = true 
	return 
}

재귀호출


처음 프로그래밍을 시작할 때 아마 가장 이해하기 힘든 개념중 하나이다.

재귀호출은 함수 안에서 자기 자신 함수를 다시 호출하는 것을 말한다.

앞서 살펴본 함수가 동작하는 방법과 동일하다.

예제를 살펴보자.

package main

import "fmt" 

func printNo(n int )  {
	if n == 0 {
		return //종료 조건 즉 재귀 탈출 조건 
	}
	fmt.Println(n)
	printNo(n-1)  //재귀 호출 
	fmt.Println("After",n)//재귀 호출 후에 출력함 
}
func main()  {
	printNo(3) //함수호출 

}

재귀함수에서 중요한 것은 종료조건과 함수가 스택으로 쌓인다는 점이다.

함수가 호출될때마다 스택메모리에 함수의 순서가 쌓인다.

처음에 printNo(3)을 만나면 함수선언문으로 돌아가서 함수를 진행시킨다.

이때 n은 0이 아니기때문에 printNo(2)를 불러온다.

printNo(2)도 n은 0이 아니기 때문에 printNo(1)을 불러온다.

printNo(1)도 n은 0이 아니기 때문에 printNo(0)을 불러온다.

printNo(0)은 n이 0이기 때문에 재귀함수가 종료된다.

대략적으로 printNo(3) ⇒ printNo(2) ⇒ printNo(1) ⇒ printNo(0)

순서로 함수가 스택메모리에 저장되고

자료구조가 스택이기 때문에 마지막 함수부터 값이 산출되면서 함수가 종료된다.

Println(1)⇒Println(2)⇒Println(3)

이런 순으로 값이 출력이 될 것이다.

다른언어(c언어)에서는 스택메모리에 한계가 있지만 Go언어에서는 자동으로 스택메모리가 확장이 되기 때문에 메모리의 한계치까지 재귀함수가 진행된다.

반응형