매틀랩입문 7 차시 논리구조 ( 조건문, 반복문, 논리함수 ) 프로그램실행순서를변경하는, 결정하는중요한문장, 명령문이바로조건문 / 선택문과반복문이다. 일반적인순서에따른명령문실행방식에서벗어나조건, 환경, 경우에맞게다른처리방식 / 과정을거치게하는일이냐말로프로그램밍에서가장중요한일이요정말프로그래밍을가능하게하는일이다. 이를논리구조라한다. 명령문처리흐름을말한다. 1. 조건문 / 선택문 이를연습하려면가장많이쓰는방법은점수에맞는학점을부여하는프로그래밍이다. if 문과 switch case 문을연습하고그차이를보여준다. 하여튼설명, 정의이런것보다는실질적인연습이더필요하고중요하다고생각하고실천하기를바라기에우린바로따라해보기, 연습해보기로들어간다. 1-1. for 문 (1) 점수가주어지면이에맞는학점을출력하는함수를만들자. function grade=hakjeom(a) if a>=90, grade='a'; elseif a>=80, grade='b'; elseif a>=70, grade='c'; elseif a>=60, grade='d'; else, grade=''; 실행해보기함수이름을부르고입력인자을 ( ) 안에넣으면된다. 92점이면 A 학점이나와야한다. >> grade=hakjeom(92) A 잘됐고, 69점은 D 학점 >> grade=hakjeom(69) D
59점은 이다. >> grade=hakjeom(59) 잘된다. 문제는 100 점이이상이면어떻게할것인지? 입력값이정확히범위안에들어온다는 가정에서프로그래밍할것인지입력값의범위등을사전에필터링할것인지의문제이다. (2) 두번째문제는 입력점수가숫자하나가아닌여러숫자의묶음 ( 벡터, 행렬 ) 로들어온다면 어찌되겠는가 이다. 매틀랩은대단위자료를처리하기위한행렬기반수학처리 S/W 이면벡터화 가중요하다고강조해왔다. >> grade=hakjeom([59,60,90,100]) 여러자료를넣어도단하나의값만처리하여반환 (return) 한다. 이러한숫자묶음 ( 벡터, 행렬 ) 을처리하려면논리함수 (find) 를사용해야한다. 뒤에서살펴보도록한다. 1-2. switch, case 문 이제 switch, case문을사용해보자. 다중분기문 으로는 if, elseif, elseif else 보다는 switch, case 문제보기편하고생각하기편하다. 이는범위지정이되지않고정확히일치하는 (==) 조건이어야한다. 이를위해 10으로나누고소수값을버림으로써 a=[6 7 8 9] 의정수값만나오도록처리하였다. (1) 첫번째시도 function grade=hakjeom2(a) a=floor(a/10); switch a case 9, grade='a'; case 8, grade='b'; case 7, grade='c'; case 6, grade='d'; otherwise, grade=''; >> grade=hakjeom2(89)
B 잘되는데 100 점이면 가된다. >> grade=hakjeom2(100) 100 점이면 10 으로변환되는데위의조건이아니므로 (6, 7, 8, 9) otherwise 즉위조건이아니면에 걸려만점을맞고도 가될수밖에없다. 제대로처리하려면 case 10 을넣든지다른방법을생 각해야한다. (2) 두번째시도 function grade=hakjeom2(a) a=floor(a/10); switch a case 10, grade='a'; case 9, grade='a'; case 8, grade='b'; case 7, grade='c'; case 6, grade='d'; otherwise, grade=''; >> grade=hakjeom2(100) A >> grade=hakjeom2(110) >> grade=hakjeom2(108) A >> grade=hakjeom2(118) 100 점은잘되는데 108 점이면 A. 뭐 100 점이상도나오면모두 A 로한다 (?). 그런데 118 점이면 또이상해진다. 할수없이입력값을필터링 ( 확인하여오류처리하는것 ) 해야한다.
if a>100 a<0, error( Input value should be between 0 and 100! ), 여기서처리할점수를여러개넣어보면 >> grade=hakjeom2([80, 90, 77, 118]) SWITCH 표현식은스칼라또는문자열상수여야합니다. 오류발생 : hakjeom2 (line 3) switch a 아예입력값은스칼라 ( 단일숫자 ) 여야한다고나온다. 2. 논리함수, find() 이제논리함수를써서복수의자료를처리하도록해보자. 매틀랩정신에맞게 function grade=hakjeom3(a) e1=find(a>=90); grade(e1)='a'; e2=find(a<90 & a>=80); grade(e2)='b'; e3=find(a<80 & a>=70); grade(e3)='c'; e4=find(a<70 & a>=60); grade(e4)='d'; e5=find(a<60); grade(e5)=''; 조건에맞는인덱스번호를추출하여이번호에해당되는것만처리한다.. if 문은 위의조건이 아니면서또다른조건에맞으면 (elseif) 식으로사용할수있지만 find() 문에서는범위를모두지 정해야한다. 그래서아예 100 점보다크거나 0 점보다작은점수입력을막는것은쉽다. 일단숫자하나를처리해도잘된다. >> grade=hakjeom3(80) B 여러숫자를입력해도잘된다. >> grade=hakjeom3([80, 90, 77, 118]) BACA function grade=hakjeom3(a) e1=find(a<100 & a>=90); grade(e1)='a';
e2=find(a<90 & a>=80); grade(e2)='b'; e3=find(a<80 & a>=70); grade(e3)='c'; e4=find(a<70 & a>=60); grade(e4)='d'; e5=find(a<60 & a>=0); grade(e5)=''; 범위를넘는자료를넣으면 >> grade=hakjeom3([100,102, 88, 95]) A BA 다소의문제가있지만하여튼처리하였다. 3. 반복문 (1) 구구단연습 어떤프로그램 ( 밍 ) 언어에도반복문연습에항상구구단이나온다. 우리도구구단을연습해보자. % gugudan for k=2:9 for kk=1:9 fprintf('%d x %d = %d \n', k, kk, k*kk) 2 x 1 = 2 2 x 2 = 4 2 x 3 = 6 2 x 4 = 8 2 x 5 = 10 2 x 6 = 12 2 x 7 = 14 2 x 8 = 16 2 x 9 = 18 3 x 1 = 3 3 x 2 = 6 3 x 3 = 9 ( 이하생략 )
2 단, 3 단마다몇단입니다. 라고쓰고단끼리분리하려면 for k=2:9 다음에출력문을넣는다. % gugudan for k=2:9 disp(' ') disp([num2str(k) ' 단입니다 ]) for kk=1:9 fprintf('%d x %d = %d \n', k, kk, k*kk) disp() 와 fprinft() 연습하려고둘을모두넣었다. >> gugudan 2 단입니다 2 x 1 = 2 2 x 2 = 4 2 x 3 = 6 2 x 4 = 8 2 x 5 = 10 2 x 6 = 12 2 x 7 = 14 2 x 8 = 16 2 x 9 = 18 3 단입니다 3 x 1 = 3 3 x 2 = 6 3 x 3 = 9 ( 이하생략 ) (2) 학점처리함수연습이제학점처리프로그램에반복문을넣어서다시연습해본다. 논리함수로복수자료를처리하는매틀랩과같은 S/W가아닌범용프로그램언어에서는반복문을써서자료하나하나를불러처리해야한다. function grade=hakjeom4(a)
n=length(a); for k=1:n if a(k)>=90, grade(k)='a'; elseif a(k)>=80, grade(k)='b'; elseif a(k)>=70, grade(k)='c'; elseif a(k)>=60, grade(k)='d'; else, grade(k)=''; 이제서야자료묶음을처리할수있게되었다. 그러나한번에하나씩 >> g=hakjeom4( jeomsu) ACBDBAAB 우리의 find() 함수는한번에처리. 그러니반복문과조건문 / 선택문을하나로융합시킨매틀랩의자 랑이랄까? >> g=hakjeom3( jeomsu) ACBDBAAB (3) 행렬점수처리 이제벡터가아닌행렬자료를처리해보자. >> B=[ 50 60 70 80; 88 99 77 66]; >> g=hakjeom3(b) BDACCBD 행렬의행과열로분리하지않고한자리인덱스로만들어처리하였다. >> g=hakjeom4(b) BDA 이건 1 행밖에처리하지않는다. length(g) 에서열수만반환되어그렇다. 다음과같이하면모두 출력될것이다. %n=length(a);
n=prod(size(a)); >> g=hakjeom4(b) BDACCBD 제대로출력되었다. 물론행렬이아닌벡터로처리되었지만 먼저반복문을사용하는함수에서는행과열로이중으로반복문을사용하면된다. function grade=hakjeom4b(a) [r,c]=size(a); for k=1:r for kk=1:c if a(k,kk)>=90, grade(k,kk)='a'; elseif a(k,kk)>=80, grade(k,kk)='b'; elseif a(k,kk)>=70, grade(k,kk)='c'; elseif a(k,kk)>=60, grade(k,kk)='d'; else, grade(k,kk)=''; >> g=hakjeom4b(b) DCB BACD 4. find() 로행렬자료처리 마지막으로 find() 를써서해보면 function grade=hakjeom3b(a) [e1,f1]=find(a<=100 & a>=90); grade(e1,f1)='a'; [e2,f2]=find(a<90 & a>=80); grade(e2,f2)='b'; [e3,f3]=find(a<80 & a>=70); grade(e3,f3)='c'; [e4,f4]=find(a<70 & a>=60); grade(e4,f4)='d'; [e5,f5]=find(a<60 & a>=0); grade(e5,f5)='';
조건에맞는행렬의인덱스번호를행과열의 2 가지로추출해서사용하면된다. >> g=hakjeom3b(b) DCD BDCD 2015-05-22, 곽노태