이 페이지의 최신 내용은 아직 번역되지 않았습니다. 최신 내용은 영문으로 볼 수 있습니다.

제어 흐름

조건부 제어 — if, else, switch

조건문을 사용하면 런타임에 실행할 코드 블록을 선택할 수 있습니다. 가장 단순한 형태의 조건문은 if 문입니다. 예를 들면 다음과 같습니다.

% Generate a random number
a = randi(100, 1);

% If it is even, divide by 2
if rem(a, 2) == 0
    disp('a is even')
    b = a/2;
end

if 문은 키워드(선택 사항) elseif 또는 else를 사용하여 다른 선택 항목을 포함할 수 있습니다. 예를 들면 다음과 같습니다.

a = randi(100, 1);

if a < 30
    disp('small')
elseif a < 80
    disp('medium')
else
    disp('large')
end

또는, 알고 있는 일련의 값과 같은지 테스트하려는 경우 switch 문을 사용합니다. 예를 들면 다음과 같습니다.

[dayNum, dayString] = weekday(date, 'long', 'en_US');

switch dayString
   case 'Monday'
      disp('Start of the work week')
   case 'Tuesday'
      disp('Day 2')
   case 'Wednesday'
      disp('Day 3')
   case 'Thursday'
      disp('Day 4')
   case 'Friday'
      disp('Last day of the work week')
   otherwise
      disp('Weekend!')
end

ifswitch 모두에 대해 MATLAB®에서는 첫 번째 true 조건에 해당하는 코드를 실행하고 코드 블록을 종료합니다. 각각의 조건문에는 end 키워드가 필요합니다.

알고 있는 이산 값이면서 값의 개수가 많을 때는 일반적으로 switch 문을 사용하는 편이 if 문을 사용하는 것보다 읽기 편합니다. 하지만 switch 값과 case 값 간에 부등식을 테스트할 수는 없습니다. 예를 들어, 다음과 같은 조건 유형은 switch로는 구현할 수 없습니다.

yourNumber = input('Enter a number: ');

if yourNumber < 0
    disp('Negative')
elseif yourNumber > 0
    disp('Positive')
else
    disp('Zero')
end

조건문의 배열 비교

관계 연산자와 if 문이 행렬에 대해 동작하는 방식을 이해하는 것은 중요합니다. 두 변수 간의 등식을 확인하려는 경우 다음을 사용해야 할 수 있습니다.

if A == B, ...

이는 유효한 MATLAB 코드이며, AB가 스칼라일 경우 예상대로 동작합니다. 하지만 AB가 행렬인 경우 A == B는 이 두 행렬이 같은지 여부를 테스트하지 않으며 두 행렬의 어느 부분이 같은지를 테스트합니다. 그 결과로, 요소별 동일성을 나타내는 0과 1로 구성된 또 다른 행렬이 만들어집니다.

A = magic(4);
B = A;
B(1,1) = 0;

A == B

ans =

  4×4 logical array

   0   1   1   1
   1   1   1   1
   1   1   1   1
   1   1   1   1

두 변수 간의 동일성을 확인하는 올바른 방법은 isequal 함수를 사용하는 것입니다.

if isequal(A, B), ...

isequalif 함수 실행 결과로, 행렬 대신 스칼라 논리값 1(true에 해당) 또는 0(false)을 반환합니다. 위의 A 행렬과 B 행렬을 사용하면 다음과 같은 결과를 얻게 됩니다.

isequal(A,B)

ans =

  logical

   0

다음은 이러한 부분을 보다 중점적으로 설명하기 위한 또 다른 예제입니다. AB가 스칼라인 경우 다음 프로그램은 절대 “예기치 못한 상황”에 도달하지 않습니다. 하지만 이전에 소개한, 열을 서로 교환한 마방진을 포함해 대부분의 행렬 쌍에서는 A > B, A < B, A == B 중 어떤 행렬 조건도 모든 요소에 대해 true가 아니므로 else 절이 실행됩니다.

if A > B
   'greater'
elseif A < B
   'less'
elseif A == B
   'equal'
else
   error('Unexpected situation')
end

다음을 포함한 여러 함수가 if 조건 사용 시 행렬 비교 결과를 스칼라 조건으로 줄이는 데 도움이 됩니다.

isequal
isempty
all
any

루프 제어 — for, while, continue, break

이 섹션에서는 프로그램 루프를 제어하는 다음 MATLAB 함수에 대해 다룹니다.

for

for 루프는 특정 명령문 그룹을, 미리 지정된 고정 횟수만큼 반복해서 실행합니다. 이와 짝을 이루는 end는 해당 명령문의 끝을 표시합니다.

for n = 3:32
   r(n) = rank(magic(n));
end
r

내부 명령문이 세미콜론으로 끝나면 출력이 반복해 표시되지 않으며, 루프 뒤에 r이 있으면 최종 결과만 표시됩니다.

특히, 루프가 중첩되어 있는 경우에는 가독성을 높이기 위해 루프를 안쪽으로 들여쓰는 것이 좋습니다.

for i = 1:m
   for j = 1:n
      H(i,j) = 1/(i+j);
   end
end

while

while 루프는 논리 조건의 제어에 따라 특정 명령문 그룹을 무한으로 반복해서 실행합니다. 이와 짝을 이루는 end는 해당 명령문의 끝을 표시합니다.

다음은 구간 이분법을 사용하여 다항식의 해를 찾는 완전한 프로그램으로, 여기에는 while, if, else, end가 포함되어 있습니다.

a = 0; fa = -Inf;
b = 3; fb = Inf;
while b-a > eps*b
   x = (a+b)/2;
   fx = x^3-2*x-5;
   if sign(fx) == sign(fa)
      a = x; fa = fx;
   else
      b = x; fb = fx;
   end
end
x

그 결과로 다음과 같이 다항식 x3 – 2x – 5의 근을 얻게 됩니다.

x =
   2.09455148154233

if 문에 대한 섹션에 설명된 행렬 비교 관련 주의 사항은 while 문에도 적용됩니다.

continue

continue 문은 for 루프 또는 while 루프에서 루프 본문의 나머지 명령문을 건너뛰고 다음 번 반복 위치로 제어를 전달합니다. 이는 중첩 루프에 있는 continue 문의 경우에도 마찬가지입니다. 즉, continue 문이 발견된 루프의 시작 부분에서 실행이 계속 진행됩니다.

아래 예제에서는 파일 magic.m에서 모든 비어 있는 라인과 주석을 건너뛰고 코드 라인 수를 세는 continue 루프를 보여줍니다. continue 문은 비어 있는 라인이나 주석 라인이 발견될 때마다 개수를 늘리지 않고 magic.m의 다음 라인으로 이동하는 데 사용됩니다.

fid = fopen('magic.m','r');
count = 0;
while ~feof(fid)
    line = fgetl(fid);
    if isempty(line) || strncmp(line,'%',1) || ~ischar(line)
        continue
    end
    count = count + 1;
end
fprintf('%d lines\n',count);
fclose(fid);

break

break 문을 사용하면 for 루프 또는 while 루프가 조기에 종료됩니다. 중첩 루프의 경우 break는 해당 루프만 조기에 끝냅니다.

다음은 이전 섹션에서 다룬 예제를 개선한 것입니다. 여기에 break를 사용하는 것이 좋은 이유는 무엇일까요?

a = 0; fa = -Inf;
b = 3; fb = Inf;
while b-a > eps*b
   x = (a+b)/2;
   fx = x^3-2*x-5;
   if fx == 0
      break
   elseif sign(fx) == sign(fa)
      a = x; fa = fx;
   else
      b = x; fb = fx;
   end
end
x

프로그램 종료 — return

이 섹션에서는 실행이 완료되기 전에 프로그램을 종료하는 데 사용할 수 있는 MATLAB return 함수에 대해 다룹니다.

return

return은 명령의 현재 시퀀스를 종료하고 호출 함수 또는 키보드로 제어를 반환합니다. 또한 returnkeyboard 모드를 종료하는 데에도 사용됩니다. 호출된 함수는 일반적으로 함수 끝에 도달하면 호출한 함수에 제어를 전달합니다. 호출된 함수 내에 return 문을 삽입하여 강제로 조기에 종료되도록 하고 호출한 함수로 제어를 전달할 수 있습니다.

벡터화

MATLAB 프로그램의 실행 속도를 높이기 위한 한 가지 방법은 프로그램을 구성할 때 사용하는 알고리즘을 벡터화하는 것입니다. 다른 프로그래밍 언어에서는 for 루프나 DO 루프를 사용할 수 있는 데 비해 MATLAB에서는 벡터 연산 또는 행렬 연산을 사용할 수 있습니다. 로그 테이블을 생성하는 간단한 예를 하나 들어보겠습니다.

x = .01;
for k = 1:1001
   y(k) = log10(x);
   x = x + .01;
end

이와 동일한 코드의 벡터화된 버전은 다음과 같습니다.

x = .01:.01:10;
y = log10(x);

좀 더 복잡한 코드의 경우에는 벡터화로 프로그래밍하는 게 더 어려울 수 있습니다.

사전할당(Preallocation)

코드의 일부를 벡터화할 수 없는 경우 출력 결과가 저장되는 벡터나 배열을 사전에 할당해 놓는 방식으로 for 루프의 실행 속도를 높일 수 있습니다. 예를 들어, 이 코드에서는 함수 zeros를 사용하여 for 루프에서 생성될 벡터를 사전에 할당해 놓습니다. 이렇게 하면 for 루프의 실행 속도가 훨씬 빨라지게 됩니다.

r = zeros(32,1);
for n = 1:32
    r(n) = rank(magic(n));
end

위의 예제에서 사전할당을 사용하지 않으면 MATLAB 인터프리터에서는 루프를 돌 때마다 요소 하나씩, r 벡터를 확장하게 됩니다. 벡터 사전할당을 활용하면 이 단계를 수행할 필요가 없어 실행 속도가 빨라집니다.