GNU Octave 구문(Statements)

GNU Octave 구문(Statements)

프로그램의 실행 흐름을 만드는 조건문과 반복문을 Octave에서 어떻게 쓰는지 살펴볼게요. if로 분기하고, switch로 값에 따라 여러 갈래로 나누고, while·do-until·for로 반복하는 기본기를 다져요.

출처: GNU Octave 구문

본문

if 문

if 문은 Octave의 의사결정 구문이에요. 가장 단순한 형태는 이렇죠.

if (condition)
  then-body
endif

condition이 참이면 body가 실행돼요. if 문의 조건은 값이 0이 아니면 참, 0이면 거짓으로 판단돼요. 조건이 벡터나 행렬이면 비어 있지 않고 모든 원소가 0이 아닐 때만 참이에요. 개념적으로 if (matrix)if (all (matrix(:)))와 같아요.

두 번째 형태는 else를 써서 참/거짓을 나눠요.

if (rem (x, 2) == 0)
  printf ("x is even\n");
else
  printf ("x is odd\n");
endif

세 번째이자 가장 일반적인 형태는 elseif로 여러 조건을 한 문에서 결합해요. elseif 절은 여러 개가 올 수 있고, 각 조건을 차례로 검사해 처음으로 참인 것의 body만 실행해요.

if (rem (x, 2) == 0)
  printf ("x is even\n");
elseif (rem (x, 3) == 0)
  printf ("x is odd and divisible by 3\n");
else
  printf ("x is odd\n");
endif

주의할 점이 있어요. elseif를 Fortran처럼 else if라고 띄어 쓰면 안 돼요. 띄어 쓰면 Octave가 다른 if 문의 else 절 안에 새 if 문이 들어온 걸로 해석해서, 첫 if를 완성할 추가 입력을 기대하게 돼요.

switch 문

하나의 변수 값에 따라 다른 동작을 하는 건 프로그래밍에서 정말 흔하죠. if로도 가능하지만 코드가 장황해져요. switch 문이 이 문제를 해결해 줘요.

switch (X)
  case 1
    do_something ();
  case 2
    do_something_else ();
  otherwise
    do_something_completely_different ();
endswitch

label은 아무 표현식이나 될 수 있어요. 다만 중복된 label 값은 감지되지 않고, 첫 번째 일치하는 command_list만 실행돼요. label이 셀 배열이면 그 원소 중 하나라도 일치하면 실행돼요.

A = 7;
switch (A)
  case { 6, 7 }
    printf ("variable is either 6 or 7\n");
  otherwise
    printf ("variable is neither 6 nor 7\n");
endswitch

switch의 장점 중 하나는 label문자열일 수 있다는 거예요. if (X == "a string")처럼 쓰면 문자열이 아니라 문자 하나하나를 비교하게 되어 유효하지 않은데, switch는 이 특수한 경우를 제대로 처리해요.

switch (X)
  case "a string"
    do_something
endswitch

while 문

루프는 두 번 이상 연속 실행되는 프로그램 부분이에요. while은 Octave에서 가장 단순한 반복문으로, 조건이 참인 동안 문장을 반복해요. 조건 판정 규칙은 if와 같아요(0이 아니면 참, 벡터면 전부 0이 아닐 때 참).

while (condition)
  body
endwhile

먼저 조건을 검사하고, 참이면 body를 실행한 뒤 다시 조건을 검사해요. 처음부터 거짓이면 body는 한 번도 실행되지 않아요. 피보나치 수열의 처음 10개 원소를 만드는 예시예요.

fib = ones (1, 10);
i = 3;
while (i <= 10)
  fib (i) = fib (i-1) + fib (i-2);
  i++;
endwhile

do-until 문

do-untilwhile과 비슷하지만, 조건이 참이 될 때까지 반복하고 조건 검사가 루프 에 있어서 body가 항상 최소 한 번은 실행돼요.

do
  body
until (condition)

피보나치 예시를 다시 쓰면 이렇게 돼요.

fib = ones (1, 10);
i = 2;
do
  i++;
  fib (i) = fib (i-1) + fib (i-2);
until (i == 10)

for 문

for 문은 루프 반복 횟수를 세기 좋게 만들어 줘요.

for var = expression
  body
endfor

일반 대입과 달리 for의 대입은 표현식의 전체 결과가 아니라 각 열을 차례로 var에 대입해요. expression이 범위·행 벡터·스칼라면 var는 매번 스칼라가 되고, 열 벡터·행렬이면 var는 매번 열 벡터가 돼요.

fib = ones (1, 10);
for i = 3:10
  fib(i) = fib(i-1) + fib(i-2);
endfor

3:10을 먼저 평가해 범위를 만들고, i에 첫 원소를 대입해 body를 실행하고, 다음 값을 대입해 반복해요. 행렬이나 셀 배열도 for로 순회할 수 있어요. 이 경우 i는 행렬(또는 셀 행렬)의 각 열을 값으로 갖게 돼요.

for i = [1,3;2,4]
  i
endfor

이 루프는 두 번 반복하면서 [1;2], [3;4] 두 열 벡터를 만들어요. 다차원 배열은 reshape (c, rows (c), prod (size (c)(2:end)))로 2차원으로 바꿔 같은 동작을 해요. 모든 forwhile로 다시 쓸 수 있지만, for가 타이핑도 적고 생각하기도 자연스러워서 둘 다 제공돼요.

더 알아보기