함수 정의하기

함수 정의하기 (Defining Functions)

가장 간단한 형태로, name이라는 함수의 정의는 이렇게 생겼어요. 함수는 Octave 문장들의 모음인 본문(body)을 갖고, 이 본문이 함수가 실제로 무엇을 하는지 결정해요.

출처: 문서

본문

가장 간단한 형태로, name이라는 함수의 정의는 다음과 같아요.

function name
  body
endfunction

유효한 함수 이름은 유효한 변수 이름과 같아요: 숫자로 시작하지 않는 문자·숫자·밑줄의 나열이죠. 함수는 변수와 이름 풀을 공유해요.

함수 body는 Octave 문장들로 구성돼요. 함수가 실제로 무엇을 해야 하는지를 알려주는 가장 중요한 부분이에요.

예를 들어, 실행하면 터미널의 벨(경고음)을 울리는 함수가 있어요(가능하다면).

function wakeup
  printf ("\a");
endfunction

printf 문은 Octave에게 "\a" 문자열을 출력하라고 지시해요. 특수 문자 \a는 경고 문자(ASCII 7)를 나타내요.

일반적으로 정의한 함수에 정보를 전달하고 싶을 거예요. Octave에서 함수에 매개변수를 전달하는 문법은 다음과 같아요.

function name (arg-list)
  body
endfunction

여기서 arg-list는 함수의 인자들을 쉼표로 구분한 목록이에요. 함수가 호출되면 인자 이름들이 호출에서 주어진 인자 값을 담는 데 사용돼요. 인자 목록은 비어 있을 수도 있는데, 그 경우 이 형태는 위에 보여준 형태와 동일해요.

대부분의 경우 함수에서 어떤 값을 돌려받고 싶을 거예요. 단일 값을 반환하는 함수를 작성하는 문법은:

function ret-var = name (arg-list)
  body
endfunction

ret-var는 함수가 반환할 값을 담을 변수의 이름이에요. 함수가 값을 반환하려면 함수 본문이 끝나기 전에 이 변수가 정의되어 있어야 해요.

함수 본문에서 사용되는 변수는 그 함수에 로컬이에요. arg-listret-var에 이름이 등장하는 변수도 함수에 로컬이죠.

예를 들어 벡터 요소들의 평균을 계산하는 함수는:

function retval = avg (v)
  retval = sum (v) / length (v);
endfunction

만약 avg를 이렇게 작성했다면,

function retval = avg (v)
  if (isvector (v))
    retval = sum (v) / length (v);
  endif
endfunction

벡터 대신 행렬을 인자로 호출하면 Octave는 이런 오류를 출력했을 거예요.

error: value on right hand side of assignment is undefined

if 문의 본문이 실행되지 않아 retval이 정의되지 않았기 때문이에요. 이런 불명확한 오류를 막으려면 반환 변수가 항상 값을 갖도록 하고, 문제가 생기면 의미 있는 오류 메시지를 출력하는 게 좋아요. 예를 들어 avg는 이렇게 쓸 수 있어요.

function retval = avg (v)
  retval = 0;
  if (isvector (v))
    retval = sum (v) / length (v);
  else
    error ("avg: expecting vector argument");
  endif
endfunction

이 함수에는 아직 남은 문제가 하나 있어요. 인자 없이 호출되면 어떻게 될까요? 추가 오류 검사가 없으면 Octave는 오류의 원인 추적에 그다지 도움이 안 되는 오류 메시지를 출력할 거예요. 이런 오류를 잡을 수 있게 Octave는 각 함수에 nargin이라는 자동 변수를 제공해요. 함수가 호출될 때마다 nargin은 실제로 전달된 인자 수로 자동 초기화돼요.

function retval = avg (v)
  retval = 0;
  if (nargin != 1)
    usage ("avg (vector)");
  endif
  if (isvector (v))
    retval = sum (v) / length (v);
  else
    error ("avg: expecting vector argument");
  endif
endfunction

Octave는 .m 파일 코드로 작성된 함수가 기대보다 많은 인자로 호출되면 자동으로 오류를 보고해요. 하지만 함수가 보통 기본 인자를 가질 수 있기 때문에 인자가 너무 적을 때는 자동으로 오류를 보고하지 않아요. 다만 값을 주지 않은 변수를 사용하려 하면 오류가 발생하죠.

nargin 함수는 함수의 입력 인자 수를 알려줘요. 함수 내부에서 호출하면 함수에 전달된 인자 수를 반환하고, 최상위 레벨에서는 Octave에 전달된 명령줄 인자 수를 반환해요. 선택 인자 fcn(함수 이름 또는 핸들)으로 호출하면 그 함수가 받을 수 있는 선언된 인자 수를 반환해요. 만약 마지막 인자가 varargin이면 반환 값은 음수예요.

function [y, ia, ib] = union (a, b, varargin)

nargin ("union")
⇒  -3

프로그래밍 주의: nargin은 내장 함수나 동적으로 불러온 함수 같은 컴파일된 함수(.oct 파일)에는 동작하지 않아요.

inputname은 호출 함수의 n번째 인자 이름을 반환해요. 인자가 단순한 변수 이름이 아니면 빈 문자열을 반환하죠.

silent_functions는 함수 내부 출력을 억제할지 제어하는 내부 변수를 조회·설정해요. 이 옵션이 비활성화되면 함수 본문 안에서 세미콜론으로 끝나지 않은 표현식의 계산 결과를 Octave가 표시해요. "local" 옵션으로 함수 안에서 호출하면 함수와 그 함수가 호출하는 서브루틴에 한해 지역적으로 설정을 바꾸고, 함수를 빠져나올 때 원래 값으로 복원돼요.

더 알아보기

  • 함수 파일과 스크립트 파일, 여러 반환 값, 가변 길이 인자 목록 등에 대한 내용을 이어서 보면 좋아요.
  • nargin, nargout, varargin, inputname 함수도 함께 살펴보세요.