반응형
Recent Posts
Recent Comments
Link
관리 메뉴

공머씨의 블로그

내가 공부한 옥타브 11.반복문 조건문 본문

내가 공부한 옥타브(매틀랩)/내가 공부한 옥타브

내가 공부한 옥타브 11.반복문 조건문

공머씨 2020. 3. 13. 12:09
반응형

 

이번에 공부하는 내용 들은 2학기에 하게 될 C언어에서도 나오는 내용들이므로 잘 공부해두시기 바랍니다.

아래와 같은 내용들을 공부하게 될 것입니다.

1. 반복문과 조건문

2. loop의 개념

loops는 고리라는 뜻을 가지고 있습니다. 아래에서 코드를 보면서 자세히 설명하도록 하겠습니다.

 

컴퓨터는 사람과 달리 반복적인 일에서 실수 없이 빠르게 계산해냅니다.

그래서 반복하는 일을 시키기에 아주 좋습니다.

옥타브에서 다룰 반복문은 for문과 while문입니다.

 

 

1. 먼저 for문의 문법은 다음과 같습니다.

for 조건

조건을 만족시킬 때까지 값을 넣을 수 있는 함수

end

 

 

문법

for 변수= 시작 값 : 증분 :끝 값

statement ()

end

 

 

설명으로만 봐서는 감이 안 잡힐 겁니다.

직접 여러 번 코딩해보셔서 익히시길 바랍니다.

축구를 잘하려면 축구이론도 중요하지만 축구를 직접 많이 해보면서 몸이 기억하게 해야 하는 것처럼

코딩도 이론이  중요하지만 손으로 직접 쳐보면서 손이 기억할 수 있도록 해야 한다고 생각합니다.

 

 

0. 간단한 코드부터 실행해보겠습니다.

%반복문 for
for a=1:1:10
  a
endfor

 

a라는 변수가 1부터 10까지 1의간격을 두고 증가합니다.

한번증가하고 endfor에 막히고... 막히면 2번줄의 for조건으로 돌아와서 다시 한번증가하고 ,, 막힉

이렇게 반복하는 형태입니다.

10을 넘어가면 조건을 벗어나기때문에 

Command window창에 10까지만 출력된것을 볼 수 있습니다.

 

 

 

1.

x=ones(1,10)
for n=2:6
 x(n)=2*x(n-1)
end

위와 같은 코드를 입력해봅니다.

그냥 해봅니다.

코드를 해석해 보겠습니다.

 

첫 번째 줄에서 x라는 행렬을 할당해 주었습니다.

ones()라는 함수는 모든 원소가 1로 구성된 행렬을 생성하는 함수입니다.

ones(행의 수, 열의 수)로 출력해줍니다.

첫 번째 줄에서 x라는 행렬은

행이 1이고 열이 10이면서 모든 원소가 1로 구성된 행렬임을 알 수 있습니다.

 

두 번째 줄에서 작성된 코드는 사전에 할당된 행렬에서 2번째 원소부터 6번째 원소까지 1씩 늘어나는 for 루프 안에 들어가도록 합니다. n은 index 번호입니다.

세 번째 줄에서 x(n)=2*x(n-1) 함수는 for문에서 설정해준 대로 2번째 원소부터 6번째 원소까지

1씩 늘어나면서 x(n) 함수에 들어가게 됩니다.

for문 이 한번 돌 때 n이 1씩 증가하면서 x(n) 함수 안에 들어가게 됩니다.

마지막 줄에서 end로 닫아줍니다.

이게 for문 시작부터 end까지가 한 루프라고 할 수 있습니다.

 

그리고 x라는 행렬이 어떻게 변했는지 알아보려면 루프 밖 (end를 입력한 뒤에)에 x를 한번 입력해줍니다.

위의 그림과 같이 2번째 원소부터 6번째 원소 까지는 x(n) 함수에 들어간 것을 볼 수 가있습니다.

 

comandwindow에 나타난 결과는 다음과 같습니다.

결과를 살펴보면 원소가 2에서 6까지 한 번에 바뀐 것이 아닌

for문을 돌면서 n이 1씩 커지므로 차례대로 바뀐 것을 볼 수 있습니다.

 

아래와 같은 과정을 거쳐서 결과가 나온 것입니다.

 

n이 6이 되면 loop 가 끝나기 때문에 n=6이 될 때까지 위의 그림과 같은 과정을 계속 반복하게 됩니다.

 

2.

for v=1.0:-0.2:0.0
 disp(v)
end

위와 같은 코드를 입력해줍니다.

코드를 해석해보겠습니다.

첫 번째 줄에서 v라는 행렬은 1.0부터 0.0까지 –0.2씩 증가하는 행렬입니다.

두 번째 줄에서 disp() 내장 함수는 display의 약자로 만든 이름입니다. 보여준다는 뜻입니다.

disp(v)는 v행렬을 보여준다는 뜻입니다.

마지막 세 번째 줄에서 endfor(또는 end로) 마무리를 해줍니다.

 

two라는m파일로 저장한 뒤 command window에 실행시킨 결과입니다.

 

two를 입력하니 m파일로 저장한 문법이 실행됨을 볼 수가 있습니다.

여기서 마지막 값이 0이라서 v를 입력하면 0이 출력되는 것 또한 볼 수 있습니다.

입력해서 확인해보시기 바랍니다.

 

>>> 왜냐하면 v에 저장된 최종적인 값은 0이므로 

v=1

v=0.8000

v=0.6000

...

v=0

로 for문안에서 실행되기 때문입니다.

 

 

 

3.

A=zeros(5,5)
for m=1:5
 for n=1:5
    A(m, n)=1/(m+n-1)
 end
end

Comand Window에서 바로 실행해본모습입니다.

코드가 끝날 때마다 ; 를 입력하지 않으면 알다시피 코드의 결과가 바로바로 실행됩니다.

예를 들어 A=zero(5,5)로 입력한 뒤 엔터를 치고 다음 코드를 입력하려고 하면

5행 5 열이고 모든 원소가 0으로 구성된 행렬 A가 바로 출력됩니다.

;를 입력해주면 행렬  A의 모습이 바로 나타나지 않고  다음 코드를 바로 입력할 수가 있습니다.

 

Editor에서 코드를 입력한 뒤 three라는 이름의 m파일로 저장해서 실행시켜 주었습니다. (행렬 A의 변화과정까지 같이 볼 수가 있습니다.)

 

 

코드를 알아보겠습니다.

 

zeros() 함수는 모든 원소가 0으로 구성된 행렬을 생성하는 내장 함수입니다.

ones()와 같이 괄호 안의 인자는 행의 수, 열의 수를 의미합니다.

그래서 A=zeros(5,5)라는 코드는 

5행 5 열이면서 모든 원소가 0으로 구성된 행렬 A를 뜻합니다.

 

 

위와 같이 for문이 2개 이상으로 사용되었을 때는

1번에서 순차적으로 내려와서 안쪽 루프까지 한번 실행된 다음

1번 루프가 for의 반복 조건까지 계속 실행됩니다.

그런 뒤에

2번 루프가 실행됩니다.

더 친절하게 설명하면 다음과 같습니다.

 

첫 번째 루프 안에서 일어나는 일입니다.

1. 1번부터  첫 번째 루프의  endfor가(5번째 줄) 나오기 전까지 한번 실행합니다. (맨 왼쪽 1이라고 쓰여있는 주황색 화살표)

2. 그다음 루프 1의 for를 반복하지 않았기 때문에 endfor를 (5번째 줄) 빠져나가지 못하고 루프 1을 계속 실행합니다. (숫자 1 옆의 점선 화살표)

>> 언제 까지 실행하냐면 n이 1부터 5까지 1씩 증가해서 5가 될 때까지 실행합니다.

3. n이 하나씩 증가하면서 4번째 줄에 있는 함수를 한 번씩 출력하게 됩니다.

위 과정까지 나온 것이 아래의 comandwindow창입니다.

1행은 그대로 있고 

1열부터 5열까지 열이 하나씩 증가하면서 함수에 대입한 값들로 원소가 바뀐 것을 확인할 수 있습니다.

 

 

루프 1이 한번 완료된 뒤 검은색 화살표를 따라서 빠져나갑니다.

루프 2가 아래 그림과 같이 한번 돌아갑니다. m=2가 되었습니다.

m은 2인 상태에서 (행이 2 인 상태에서 ) 루프 1로 들어가서 n이 1에서 5까지 1씩 증가하는 과정을 거쳐서 

루프 1을 빠져나오게 됩니다.

 

루프 2에서 m=3이 됩니다.

세 번째 행에서 또 열이 1부터 5까지 1씩 증가하면서 원소의 값이 바뀌게 됩니다.

.

.

.

이런 과정들을 거쳐서 최종적으로 출력되는 결과는 아래와 같습니다.

 

A =

    1.00000     0.50000       0.33333      0.25000    0.20000

    0.50000     0.33333      0.25000       0.20000     0.16667

    0.33333     0.25000       0.20000      0.16667      0.14286

    0.25000     0.20000        0.16667     0.14286      0.12500

    0.20000     0.16667       0.14286      0.12500      0.11111

 위와 같이 대각선의 원소끼리 같아진 것을 확인할 수 있습니다.

왜 그런지는 위의 함수가 (4번째 줄 코드 )'행과 열이 정의역이 되어 만들어지는 함수'임을 생각하면 알 수 있습니다.

 

 

+

Work space까지 같이 보려면 comand window의 맨 위에 있는 바에서 window를 선택하셔서 찾으시면 됩니다.

three라는 m파일을 입력해주니까 work space에서 A라는 행렬과 변수 m, n이 할당되어있음을 알 수 가있습니다.

그래서 comand window에서 A를 입력하면 Editor에서 입력한 문법에 따른 행렬 A가 출력되는 것입니다.

중요한 내용은 아니고 계속 코딩을 하다 보면 언젠가는 이해되는 부분이니 지금은 그냥 넘어가도 됩니다.

 

 

4. for문으로 구구단 출력해보기

1)

어떤 문법인지 확실하게 짚고 넘어갑니다.

num2str(a)

숫자를 stirng로 바꾸어 주는 함수 입니다.

for문으로 구구단을 출력하는 프로그램을 만들어 보겠습니다.

for i=1:1:9
    for j=1:1:9
       disp(i*j)
   end
end

안에있는 루프가 1부터 9까지 돌아갑니다.

그다음 작은 루프를 빠져나가서 i가 2로 바뀝니다.  아래로 쭉내려와서 다시 작은루프안에 갇히게 됩니다.

조건을 만족할때까지 루프밖을 빠져나갈수는 없습니다.

임무를 수행하면(j부터 9까지 돌아갔으면)

다시 밖으로 빠져나와서 i가 3이되고....

이런과정을 반복합니다.

 

 

2)

%이중for문으로 구구단 만들기
for i=1:1:9  
  for j=1:1:9
    disp(['i= ',num2str(i) ])
    disp(['j= ',num2str(j) ])
    i*j
  endfor
endfor

 

 

 

5. for문으로 구구단 행렬

 

 

 

 

 

Comand window창을 보면 행렬의 원소가 하나씩 채워집니다.

5번째 줄앞에 pause(1)을 입력하면 command window에서 변하는 과정을 천천히 볼수 있습니다.

pause(1) >> 1초 간격으로 코드를 실행합니다.

 

 

 

 

 

2. while문은

조건이 참이면 계속 한 루프를 실행하는 반복문입니다.

문법은 다음과 같습니다.

 

while 조건

         반복해야 할 문장(함수)

end

정확하게 짚고 넘어가야 되는 부분입니다.

expression은 논리연산이 들어가는 부분입니다.

for와 if를 합친것 이라고 생각할 수도 있습니다.반복+조건

조건을 만족하면 계속 반복을 해줍니다.

조건이 항상 참이면 무한 루프가 완성됩니다.

 

command window에서 무한 루프 멈추고 싶으시면 마우스 command window위에 놓고 Crtl+c 누르시면 되요

 

 

 

 

전체코드와 출력화면 입니다.

%counter변수를 사용해보겠습니다.
counter=0
while true  
  disp('while loop')
  counter=counter+1  %while문을 한번돌때마다 counter에 저장된 숫자가 1씩 늘어납니다.
  pause(1) %1초씩 간격을 두고 출력됩니다.
endwhile 

 

 

 

 

 

조건이 항상 

%조건이 항상거짓일때 while loop
counter=0
while false  %표현식이 거짓으로 바뀌었습니다.
  disp('while loop')
  counter=counter+1  
  pause(1) 
endwhile 

 

 

 

 

 

 

 

 

 

 

 

>> '반복해야 할 문장 (함수)'가 '조건'에 맞는 참일 경우에 '반복해야 할 문장(함수)'을 계속 반복합니다.

1.

n=1
nFactorial = 1
while nFactorial <1 e100
  n=n+1
  nFactorial=nFactorial*n
end

 

Editor에서 코드를 입력할 때 한 줄끝 날 때마다 ;을 입력하지 않았습니다.

위와 같은 방식으로 코딩한 뒤에 comand window에서 m파일을 실행시켜주면 n값이 순차적으로 커지고 이에 따른 nFactorial 값을 확인할 수 있습니다.

while 문이 어떻게 돌아가는지를 확인할 수가 있습니다.

 

 

 

 

 

 

 

 

 

 

m파일을 위와 같이 저장하고 실행시키면 아래와 같이 

while의 조건을  만족시키는 마지막의 n값은 70이고 

nFactorial의 값은 1.1979e+100 임을 알 수가 있습니다.

 

 

 

Comand Window에 코드를 입력하고

마지막에 nFactorial의 값이 무엇인지 알기 위해 입력한 모습입니다.

 

 

1e100보다 작으면서 가장 가까운 Factorial의 결괏값은 1.1979e+100 임을 알 수가 있습니다.

 

 

 

 

 

2.

1) command에 아래와 같은 코드를 바로 입력해봅니다.

n=10;
f=n;
while n > 1
 n=n-1;
 f=f*n;
end

 

 

 

2)

n=10
f=n
while n > 1
   n=n-1
   f=f*n
end

 

마찬가지로  ; 를 사용하지 않고 코딩한 뒤 m파일로 저장해서 실행시키면 위와 같이

n값이 순차적으로 커짐에 따른 f의 값도 같이 볼 수가 있습니다.

 

3. 조건문

조건이 참인 경우에만 명령문을 실행하는 구문입니다.

문법은 다음과 같습니다.

 

if 조건

else if

else if

else          % 마지막 조건은 else로 표기합니다.

end

 

1. 

a=randi(100,1)

if rem(a,2)==0
  disp('a is even')
  b=a/2
endif

위와 같이 입력합니다.

m파일의 이름은 ele로 저장하고 실행하였습니다.

 

ele라는 이름으로 m파일을 저장했습니다.

 

 

첫 번째 줄에서 

randi 함수는 표준 정규분포에 따라 무작위 실수를 생성하는 것에서는 rand와 같지만

생성 범위를 직접 정할 수 있습니다. (출처: 네이버)

randi(100,1)이라는 함수는 1부터 100까지의 범위에서  1차원 정방 행렬을 랜덤으로 생성하는 함수입니다.

위 그림에서 알 수 있듯이 randi () 함수로 생성된 행렬은  clear name으로 초기화시켜주기 전까지는 한번 생성된 행렬을 그대로 가지게 됩니다.

세 번째 줄에서 rem함수는

아래와 같은 뜻이 있습니다.

rem(x, y): x/y 나누세요의 나머지를 반환. 

따라서 rem(a,2)==0 코드의 뜻은 a를 2로 나누었을 때 나머지가 0인 경우를 뜻합니다.(짝수라는 이야기)

이와 같이 나머지를 반환하는 함수에는 mod() 함수가 있습니다.

차이점?

네 번째 줄에서  

disp(' ')는 따옴표 안의 문자를 그대로 보여주는 함수입니다.

다섯 번째 줄에서 b=a/2는 b라는 변수에 a를 2로 나눈 값을 대입하라는 뜻입니다.

여섯 번째 줄에서 endif라고 해주었는데 사실 end라고 해도 되기는 하나 if와 for가 엄청나게 많이 중첩된 문장을 코딩하는 경우(아래 4번에서 해볼 것입니다.)가 있기 때문에 end 보다는 endif endfor을 써주는 게 좋을 것 같다고 생각합니다.

 

 

 

 

 

2.

 

 

위의 결과창에서 a라는 변수는 

 

 

 

 

 

 

 

 

4. for 문과 if문을 혼용해서 사용해보자.

nrows=4
ncols=6
A=ones(nrows, ncols)

for c=1:ncols
 for r=1:nrows
  if r==c
    A(r, c)=5;
   elseif abs(r-c)==1
    A(r, c)=-3;
   else
     A(r, c)
   end
  end
end

 

중첩 문이라는 것은 위와 같이 루프가 여러 개로 구성된 것입니다.

 

위와 같은 코드를 입력해줍니다. five라는 이름의 m파일로 저장해 두었습니다.

 

 

 

위와 같이 Editor에 입력하셨을 거라고 생각합니다.

하나씩 생각해보겠습니다.

1. 일단 3번째 줄까지는 4행 6 열이고 모든 원소가 1로 구성된 행렬이 나옵니다.

for문 들이 실행되기 전에 행렬 A의 형태는 위와 같습니다.

2. 루프에 들어가게 됩니다.

5번째 줄, 6번째 줄에서 행 과열은 각각 1부터 정해진 값까지 증가하게 됩니다.

 

3. 7번째 줄 8번째 줄은

만약 r행 c열에서 r의 값과 c의 값이 같다면 5가 부여된다는 뜻입니다.

이게 무슨 말이냐면 3행 3열 의 경우 (3=3) 행의 숫자와 열의 숫자가 같기 때문에 5가 부여됩니다.

마찬가지로 1행 1열, 2행 2열, 3행 3열, 4행 4열 모두 같이 5가 부여됩니다.

(행의 최댓값은 4)

 

4. 9번째 줄 10번째 줄은

만약 r행 c열에서 r-c의 절댓값이 1이라면 3이 부여된다는 뜻입니다.

abs()는 절댓값을 뜻하는 내장 함수입니다...

이게 무슨 말이냐면 행과 열의 차이에 절댓값을 취했을 때 1이나 오면

>> 행의 수와 열의 수가 어느 것이 더크던지 1씩 차이 나면 됩니다,

예를 들어 1행 2열, 2행 1열, 2행 3열  , 3행 4열, 3행 2열 , 4행 5열 , 4행 3열

에 있는 원소들은 모두 3이 됩니다.

 

 

5. 11번째 줄 12번째 줄은

위의 두 가지 경우가 아니라면 1이 그대로 있다는 뜻입니다.

 

아래와 같은 결과가 출력됩니다.

 

 

 

 

5. switch조건문에 대해서 알아보겠습니다.

if조건문의 경우 하나의 값을 입력하면 그 입력값이 해당하는 경우에 따라 처리했는데

switch문은 이와 다르게 하나의 값에서 여러 가지 경우의 수를 놓고 처리합니다.

말로는 절대 한 번에 이해가 안 될 것입니다.

아래 코드를 실행해보고 익히시기 바랍니다.

문법은 그림과 같습니다.

 

a=input('x^의 계수:')
b=input('x의 계수:')
c=input('상수 계수:')
D=b^2-4*a*c
s=roots([a,b,c])
sprintf('방정식 %.2fx^2+%.2fx+%.2f=0은',a,b,c)

switch sign(D)
 case 1
  sprintf('서로다른 실근') %1
 case 0
  sprintf('중근') 
 otherwise 
  sprintf('허근')
 
endswitch

 

 input() 함수에서 작은따옴표 안에 있는 메시지가 출력되고 메시지에 해당하는 값을 입력하면 q변수 a에 할당하는 내장 함수입니다.

4번째 줄에서 D는 근의 공식에서 허근인지 실근인지(서로 다른 두실근, 중근) 임을 구별해주는 수식입니다.

 

5번째 줄 변수 s에 할당된 함수는 roots()라는 내장 함수입니다.

roots() 함수는 근의 공식을 사용해 이차방정식의 두 근을 구해주는 내장 함수입니다.

 roots() 함수 안에 []가 있는데 

[] 안에 방정식의 계수를 차례로 입력하면 됩니다. 만약 이차방정식에서 일차 항의 계수가 0이라면 생략하지 말고 0을 작성해주어야 합니다.

반응형
Comments