2016. 3. 11.

함수(Function)에 대한 팁

[출처:http://autohotkey.co.kr/b/6-272]



함수가 왜 필요할까요?
여러번 반복해서 사용하고 싶은 균일한 명령어들이 필요할때, 간편하게 사용하기 위해서 쓰는것입니다.
반복해서 쓸것도 아닌데, 간편하게 만드는 경우는, 타인에게 함수를 제공할때정도 일것 같습니다


함수가 사실 어려운게 아닌데, 딱히 쉽게 이해될 팁이 없어서 힘들어 하시는분들이 계신듯합니다.
가급적 쉽게 오토핫키의 함수에 대해 적어보겠습니다.


1. 함수의 선언함수이름(사용될변수1, 사용될변수2, 사용될변수3...)
{
실행될 명령들

return 반환값
}

함수이름 : 사용되어질 함수이름입니다.
사용될변수1,2,3... : 함수안에서 사용되어질 변수입니다.
{} 중괄호 : 꼭 중괄호로 묶여져야만 합니다.
실행될 명령들 : 함수내부에서 실행되어지는 명령들입니다.
반환값 : 함수를 실행하고 값을 반환받고 싶을때 사용되어집니다.
return : 반환하고싶은값이 없다면, return이 필요없습니다.

* 여기서부터 함수에 대해 설명할때 함수선언된 내부와 함수가 선언되지 않는 스크립트부분으로 구분하여 이해를 도왔습니다. (main으로 설명하기엔 애매한감이 있었습니다.)


2. 함수의 호출우선 예제로 사용될 함수는 아래와 같습니다.
My_Add(a) ………………………… (3)
{
return a+1  …………………………… (4)
}
b=1           …………………………… (1)
b:=My_Add(b) ………………………… (2)
msgbox % b …………………………… (5)

우선 한가지 특성을 알려드리자면, 함수가 선언되면, 그에 해당하는 중괄호의 모든내용은 실제 스크립트에서
함수를 호출하지 않는이상 스크립트내용에 지장을 안줍니다.
그러므로 함수를 어디에 선언해도 무방합니다.
다르게 말하면, 여기서 중괄호는 if나 loop문에서 쓰이는 중괄호와 다소 다른 역할을 합니다. 스크립트내용에 영향을 안주는 영역설정을 하는것입니다.

스크립트내용에 대해 보겠습니다.
(1) b=1로 선언되었죠.
(2) 그리고 My_Add함수를 b를 넣어서 호출합니다. b는 1이므로 1값을 넣은것입니다.
(3) 그러면 이제 함수부분으로 갑니다.
     여기가 중요합니다. b=1을 넣었으므로 함수안에선 a=1인 상태가됩니다.
     즉 b와 a는 서로 다른곳에 위치한 변수입니다. 전혀 동일한 변수가 아니라는 얘기입니다.
     (자세히 얘기하자면, a라는 변수는 함수를 실행할때만 일시적으로 생기는 변수입니다. 지역변수라고도 합니다.)
     또 다르게 표현하자면, 스크립트에서 함수안에 a대신 b라고 써도 b=1로 선언한 변수와는 전혀 틀린 지역변수입니다.
     다만 이름만 같을수 있을뿐입니다.
(4) return a+1 a에 1을 더한값을 반환한다는 얘기입니다.
(2) 다시 (2)로 돌아왔습니다. b:=My_Add(b)를 보면, My_Add(b)로부터 반환되는값을 b에 저장하겠다는 얘기입니다.
(5) 그러므로 msgbox % b 에서 b는 2가 출력됩니다.

사실 (1),(2),(5)는 좀더 간단히 표현할수 있습니다.
msgbox % My_Add("1")
한마디로 함수 My_Add에 1을 넣어서 반환받은값을 msgbox로 출력한다는 얘기입니다.

그러면 여기서 한가지 팁이 더 생겼죠?
값그자체로 넣을때는 My_Add("1")처럼 ""안에 넣고 변수형태로 넣을때는, My_Add(b)처럼 하면됩니다.


3. 두개이상의 반환값이 필요할때보시다싶이 return 으론 반환을 하나밖에 못하게 되어있습니다.
return없이 반환을 가능하게 해주는 명령어 두개가 있습니다. global, byref입니다.

a=3
b=3
My_Add()
msgbox % a
msgbox % b
My_Add()
{
global a
a:=a+1
b:=b+1
}

보시다싶이 My_Add엔 아무값도 안넣어서 실행을 했습니다.
그런데 결과값을보면, a=4,b=3이 출력되네요
간단합니다.
함수안에서 global a라은 명령을 실행해주면, 함수안의 a는 일시적으로 사용하는 지역변수가 아닌 스크립트에서 사용되는 a값을 사용할수 있게 해줍니다. 그러므로 함수실행후 a는 4가 되고 b는 3이 되는것입니다.
b에도 영향을 주려면, global b 라고 쓰면 되겠죠 ^^


a=3
b=3
My_Add(a,b)
msgbox % a
msgbox % b
My_Add(Byref a, Byref c)
{
a:=a+1
c:=c+1
}

Byref라고 쓰고 함수에서 변수를 선언해주면, 함수호출시 My_Add(a,b) 대입대는 변수a,b에 간섭을 가능하게 해줍니다.
근데 이상하게 생각되실수 있겠지만, Byref c라고 했음에도 불구하고, 실제 스크립트에서 쓰인 b=3값이 변하여 4가 됩니다.
포인터가 아무래도 적용이 된듯한데, 여기까진 아시면 좋지만, 굳이 알필욘없습니다.
그냥, 간편히 생각하자면, 함수호출시 a,b라고쓰고 함수선언시에는 c,d라고 써도 실제 a,b값에 간섭을 줄수 있다는 것입니다.









------------------------------------------------------------------------------------------------------------------
아마도 여기서부턴 안보셔도 대부분 함수사용시 지장이 없으실듯 합니다.
이 아래 내용은 보실분만 보세요.


4. 함수호출시 값을 안넣어도 함수가 실행되게끔하기

msgbox % My_Add("3")
msgbox % My_Add("3","4")
My_Add(a,b=1)
{
return a+b
}

보시면 함수선언에는 My_Add(a,b=1) a,b 두개가 선언되어있습니다.
하지만 b=1이라고 지정하여, b값을 입력받지 않을시, b는 기본으로 1이 되는것을 의미합니다.
그러므로 msgbox % My_Add("3") 는 4가 나오고, msgbox % My_Add("3","4") 7이 나옵니다.
한가지 주의사항이 있다면, 기본값을 지정할 변수들은 값을 무조건 넣어야 하는 변수보다 뒤쪽에 선언되어야 합니다.

Byref로 선언된 변수는 ""를 사용하는데 굳이 설명하진 않겠습니다. 스크립트만 답니다.

c=2
msgbox % My_Add("3","4")
msgbox % c
My_Add(a,b=1,byref d="")
{
d:=d+1
return a+b
}


5. 함수 호출시만 변하는 static변수
c=10
My_Add(c)
My_Add(c)
My_Add(c)

msgbox % b

My_Add(a)
{
a+=1
static b=0
b+=1
msgbox static b값 : %b%`n지역변수 a값 : %a%
}

static변수란 함수호출시에 함수안에서만 계속 영향을 받는 변수를 말합니다.
함수호출시 처음엔 static b=0 이라고 선언되지만, 그 이후엔 b=0이란 것은 무시되고 static변수로써 취급만 합니다.

그렇다면, 당연히 함수 처음실행시 b값은 1, 다음엔 2, 그다음엔 3으로 출력이 됩니다.
이미 4번까지 읽으셨다면, 자세한 설명이 없어도 이해되시라 생각합니다.



6. 함수의 응용 재귀함수우선 재귀의 국어사전 뜻을 보면,
재귀
[재ː―][再歸] <명사> 다시 본 곳으로 돌아옴. 재귀-하다 <자동사><여불규칙활용>

함수에서 얘기하자면, 함수내부에서 자신의 함수를 다시 돌아본다. 다시 실행한다 라고 얘기할수 있습니다.

스크립트에서 보겠습니다.


msgbox % My_Add("10") ………………………… (1)

My_Add(a) …………………………………………… (2)
{
if a=1  ………………………………………………… (3)
 return "1"
else …………………………………………………… (4)
 return a+My_Add(a-1)
}

(1) 우선 함수호출시 10을 넣습니다.
(2) 그럼 함수에서 지역변수 a는 10을 받습니다.
(4) else부분이 실행됩니다. 당연히 a=10이기 때문입니다.
     a+My_Add(a-1)
     즉 10+ My_Add(9)를 반환한다는 얘기입니다.
    근데 My_Add(9)를 실행하면 또 반환을 받을수 있네요.
    (2),(4)의 과정을 또 거치면, 10+9+My_Add(8)이 되겠네요.
그래서 a=1 될떄까지 계속 반복하다보면, 10+9+8+7+6+5+4+3+2+My_Add(1) 까지 오는데,
My_Add(1)은 1을 반환하므로 10+9+8+7+6+5+4+3+2+1이 됩니다.

간단히 설명하긴 했으나, Loop와는 다르게 이용할수 있습니다. ^^




* 여기까지 보셨다면, 직접 하나씩 함수를 만들어 보시거나, 사이트에 올라온 함수에 주석을 생각해 보시는건 어떠실까요?

최근에 올라온 MultipleSearch에 대해 보시는건 어떠실까요
제가 MBR님의 멀티플서치를 조금 수정해서 만든글을 보면, 재귀함수에 대해 조금은 보실수 있으실거예요
링크 : http://www.autohotkey.co.kr/cgi/board.php?bo_table=script&wr_id=483