IT/perl
090506-perl-제어문
joanne*
2009. 5. 5. 23:33
제어문의 종류
◆제어문
-순차적인 흐름을 통제하는 명령
-조건에 대응하여 다양한 처리가능
제어문의 종류
-조건문
if,unless
-반복문
while,until(else),for,foreach,do
-흐름변경
last(break), next(continue), redo(반복문의 처음으로 진행상태를 지우고 완전초기화)
IF문
[예제 1] if문의 간단한 예제
#!/usr/bin/perl
print "Input Number : ";
$Num = <STDIN>;
$Num +0;
$Num = <STDIN>;
$Num +0;
if($Num ==1){
print "One! \n";
}elsif($Num == 2)
{
print "Two \n";
}else
{
print "not equal \n";
}
print "One! \n";
}elsif($Num == 2)
{
print "Two \n";
}else
{
print "not equal \n";
}
[root@test_mt /home/joanne/perl/ex_1] ./readdir.pl
Input Number : 1
One!
[root@test_mt /home/joanne/perl/ex_1] ./readdir.pl
Input Number : 3
not equal
[root@test_mt /home/joanne/perl/ex_1] ./readdir.pl
Input Number : 2
Two
[예제 2] if문의 간단한 예제 2
#!/usr/bin/perl
print "Input First Number : ";
$Fnum = <STDIN>;
$Fnum += 0;
print "Input Second Number : ";
$Snum = <STDIN>;
$Snum += 0;
$Snum = <STDIN>;
$Snum += 0;
if($Fnum > $Snum){
print $Fnum.' is less than '.$Snum."\n";
}elsif($Fnum < $Snum){
print $Fnum.' is greater than '.$Snum."\n";
}else{
print $Fnum. 'is equal to '.$Snum."\n";
}
unless($Fnum == 0) # if의 반대
{
print 'First Number is not Zero';
}
print $Fnum.' is less than '.$Snum."\n";
}elsif($Fnum < $Snum){
print $Fnum.' is greater than '.$Snum."\n";
}else{
print $Fnum. 'is equal to '.$Snum."\n";
}
unless($Fnum == 0) # if의 반대
{
print 'First Number is not Zero';
}
[root@test_mt /home/joanne/perl/ex_1] ./ex_2.pl
Input First Number : 2
Input Second Number : 3
2 is greater than 3
Input First Number : 2
Input Second Number : 3
2 is greater than 3
FOR 문
[예제 3] for 문의 간단한 예제
#!/usr/bin/perl
for($i=1;$i<10;$i++)
{
print "$i ";
}
print "\n";
for($i=1;$i<10;$i+=2)
{
print "$i ";
}
print "\n";
for($i=1;$i<10;$i+=2)
{
print "$i ";
}
print "\n";
[root@test_mt /home/joanne/perl/ex_1] ./ex_3.pl
1 2 3 4 5 6 7 8 9
1 3 5 7 9
[예제 4] for문의 간단한 예제 2
#!/usr/bin/perl
print "input number :";
$inNum = <STDIN>;
for($i=1;$i<=$inNum;$i++)
{
$sum += $i;
}
{
$sum += $i;
}
print "Sum = $sum\n";
[root@test_mt /home/joanne/perl/ex_1] ./ex_4.pl
input number :10
Sum = 55
input number :10
Sum = 55
FOREACH문
-요소의 수만큼 반복하는 제어문
-배열에서 효율적으로 쓰임
-변수를 생략가능
foreach구문은 csh에서 사용되었던 구문인데 C프로그래머에게는 약간 생소할 수 있지만 vector형 자료를 많이 다루는 작업에서는 꼭 필요한 제어 구조이다. Perl에서는, foreach는 for의 동의어이다.
foreach scalar변수 (list형의_변수_또는_값) { # scalar변수에 대한 조작을 하는 문장들 }
[예제 5] foreach문의 예제 1
#!/usr/bin/perl
@Num1 = (1..9);
foreach $i(@Num1) # foreach $변수(@배열)
{
print "$i ";
}
print "\n";
@Num1 = (10..19);
foreach (@Num1){ #변수생략
print "$_ "; #특수변수
}
print "\n";
print "\n";
@Num1 = (10..19);
foreach (@Num1){ #변수생략
print "$_ "; #특수변수
}
print "\n";
[root@test_mt /home/joanne/perl/ex_1] ./ex_5.pl
1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
[예제 6] foreach문의 간단한 예제 2
#!/usr/bin/perl
print "input number :";
$inNum = <STDIN>;
@arrNum = (1..$inNum);
$i=1;
foreach (@arrNum)
{
$sum += $i;
}continue{
$i++;
}
{
$sum += $i;
}continue{
$i++;
}
print "Sum = $sum";
print "\n";
[root@test_mt /home/joanne/perl/ex_1] ./ex_6.pl
input number :10
Sum = 55
CONTINUE
while (조건식) {
# 조건식이 참일 때 실행되는 문장들
} continue {
# 조건식에 관계되는 변수들의 증감식(auto-in/decrement)
}
list형의 변수 또는 값에서 하나씩 scalar변수에 대입하여 list내의 각 원소들에 대해서 각각 비슷한 유형의 처리를 해 줄 수 있다. 다음은 foreach를 사용하여 현재 디렉토리에 존재하는 파일들의 permission을 바꾸어주는 예제이다.
foreach $f (`ls`) { chmod 0755, $f; # chmod는 file의 permission mode를 바꾸어주는 연산자 }
while문 & until문
-if와 unless의 관계와 비슷
$a = 0;
while ($a < 10) {
$a++;
print "$a\n"; # 1 2 3 4 5 6 7 8 9 10이 차례대로 출력된다.
}
while ($a < 10) {
$a++;
print "$a\n"; # 1 2 3 4 5 6 7 8 9 10이 차례대로 출력된다.
}
$a = 0;
until ($a >= 10) {
$a++;
print "$a\n"; # 1 2 3 4 5 6 7 8 9 10이 차례대로 출력된다.
}
다음의 예제는 위쪽의 while/until의 예제와 같은 결과를 보여준다. 그러나 위쪽의 형식보다는 보다 안전한 구문 표기법으로 볼 수 있다. continue 블럭 안에서만 증감식이 구성되는 경우 변수의 추적이 용이하다.
$i = 1; while ($i <= 10) { print "Count-up: i = $i\n"; } continue { $i++; }
FOR문
for구문의 기본적 형식은 C구문과 동일하다.
for (초기화; 조건식; 증감식) { # 조건식이 참일 동안 실행될 문장들 }
그러나 아래와 같이 Perl만의 확장된 형식도 존재한다.
for ($a .. $b) {
# $a값부터 $b값까지 $b-$a+1번 수행되는 문장들
}
# $a값부터 $b값까지 $b-$a+1번 수행되는 문장들
}
[예제 7] for문의 간단한 예제 1
#!/usr/bin/perl
for (10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) {
print "Count-down: " . $_ . "\n"; # $_에는 10 .. 0이 각각 들어간다.
}
for (0 .. 10) {
print "Count-up: " . $_ . "\n"; # $_에는 10 .. 0이 각각 들어간다.
}
for (10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) {
print "Count-down: " . $_ . "\n"; # $_에는 10 .. 0이 각각 들어간다.
}
for (0 .. 10) {
print "Count-up: " . $_ . "\n"; # $_에는 10 .. 0이 각각 들어간다.
}
[root@test_mt /home/joanne/perl/ex_1] ./ex_7.pl
Count-down: 10
Count-down: 9
Count-down: 8
Count-down: 7
Count-down: 6
Count-down: 5
Count-down: 4
Count-down: 3
Count-down: 2
Count-down: 1
Count-down: 0
Count-up: 0
Count-up: 1
Count-up: 2
Count-up: 3
Count-up: 4
Count-up: 5
Count-up: 6
Count-up: 7
Count-up: 8
Count-up: 9
Count-up: 10
do-wile, do until 구문
do/while 또는 do/until구문은 위에서 설명했던 while이나 until구문을 참고하면 그다지 어려운 개념은 아닐 듯 싶다. 많은 C프로그래머들이 알고 있다시피 do로 시작하는 구문의 while구문(until구문)과의 차이점은 조건식이 loop보다 먼저 수행되는가 아니면 loop가 최소한 한 번 수행된 후에 수행되는가의 차이이다. do구문에서는 조건식이 loop 뒤쪽에 제시되므로 최소한 1번은 조건과는 상관없이 수행됨을 알 수 있다.
do구문의 형식은 다음과 같다.
do { # 조건식이 참인 동안에 실행될 문장들 } while (조건식); do { # 조건식이 참이 될 때까지(거짓인 동안에) 실행될 문장들 } until (조건식);
다음은 같은 결과를 보여주는 do/while, do/until구문의 예제이다.
$i = 0; do { print "Count-up: $i\n"; $i++; } while ($i <= 10); $i = 0; do { print "Count-up: $i\n"; $i++; } until ($i > 10);
loop 내에서 제어를 옮기는 방법이 존재한다. next, last, redo가 그것이며, C프로그램과 비교하자면, next는 continue, last는 break와 비슷한 기능을 가지고 있다.
a) next
next는 loop내의 제어를 다음 차례로 넘기게 된다. C의 continue문과 같은 기능을 한다. 그러나 Perl에서의 continue 블럭과 C의 continue문장은 다른 의미를 가지게 된다. 다음 예제를 통해 next의 사용법을 익히도록 하자.
LINE: while (<STDIN>) { next LINE if /^#/; # 주석은 건너뛴다. next LINE if /^$/; # null line도 건너뛴다. } continue { $count++; # next에 의해 제어가 옮겨져도 count는 증가한다. }
LABEL이 어디에 위치하든 간에 next문을 만나게 되면 continue블럭에서 증감식을 수행한 후에 그 label로 제어를 옮기게 됨을 알 수 있다. C의 continue와 같이 단순하게 작동시키는 것도 어려운 일이 아니다.
for ($i = 0; $i < 10; $i++) { if ($i == 5) { next; } print "$i\n"; }
b) last
last는 loop를 빠져나오는 기능을 수행한다. loop를 빠져나오는 것이기 때문에 continue블럭내의 문장들도 당연히 수행되지 않는다. label이 loop의 가장 앞쪽을 가리킨다고 해서 loop를 다시 반복하는 것이 아님에 유의하라.
LINE: while (<>) { last LINE if /^$/; # null string을 만나면 종료한다. print; # default input string인 $_를 출력한다. }
REDO 구문
for(1..5)
{
print "Input Password : ";
$pass = <STDIN>;
chomp $pass;
if($pass eq "hackers"){
print "Access System OK \n";
last;
}
if($pass eq "hack"){
print "Access System Failed \n";
redo;
}
}
print "End !";
{
print "Input Password : ";
$pass = <STDIN>;
chomp $pass;
if($pass eq "hackers"){
print "Access System OK \n";
last;
}
if($pass eq "hack"){
print "Access System Failed \n";
redo;
}
}
print "End !";
Input Password : hack
Access System Failed
Input Password : hack
Access System Failed
Input Password : hackers
Access System OK
End !
[root@test_mt /home/joanne/perl/ex_1] cat ex_8.pl
#!/usr/bin/perl
$i=0;
$sum=0;
print "input 999 to quit\n";
print "input a number : ";
while(<>){
if($_ > 999){
print "\n input nuber from 0 to 999~!\n\n";
print "input a number : ";
}
elsif($_ != 999){
$n[$i]=$_; #save $_ in array @n
$sum += $n[$i];
$i++;
print "input a number : ";
}
else{ #quit if the input is 999
last;
}
}
print "input a number : ";
while(<>){
if($_ > 999){
print "\n input nuber from 0 to 999~!\n\n";
print "input a number : ";
}
elsif($_ != 999){
$n[$i]=$_; #save $_ in array @n
$sum += $n[$i];
$i++;
print "input a number : ";
}
else{ #quit if the input is 999
last;
}
}
print $sum."\n";
[root@test_mt /home/joanne/perl/ex_1] ./ex_8.pl
input 999 to quit
input a number : 2
input a number : 3
input a number : 6
input a number : 999
11