Valdymo ir kontrolės struktūros

 

Valdymo ir kontrolės struktūros - tai sąlygos bei ciklo sakiniai. Jie susiję su programinio kodo dalimi, kurią jie valdo. Ši dalis yra vadinama bloku ir apskliaudžiama figūriniais skliaustais { }.

{
    first_statement;
    second_statement;
    third_statement;
    ...
    last_statement;
}

Blokas, susijęs su valdymo struktūra visada turi turi būti apskliaustas { }, net jei jis ir tuščias. Blokai taip pat gali apibrėžti ir kintamųjų veikimo sritį, t.y. panaudojus funkcijas my() bei local(), blokuose lokalizuojami kintamieji. Plačiau apie tai kituose skyriuose.


Sąlygos operatoriai

Valdymo ir kontrolės struktūros susijusios su loginėmis būsenomis t. y. kontrolinė išraiška gali būti traktuojama kaip true arba false.  PERL'e kontrolinė išraiška yra nagrinėjama, kaip eilutė skaliariniame kontekste. Jei eilutė yra lygi: undef, 0, '' , '0', kontrolinė išraiška  interpretuojama kaip false, priešingu atveju kaip true. Keletas pavyzdžių:

0       # konvertuojamas į "0", todėl false
1-1     # konvertuojamas į 0, tada į "0", todėl false
1       # konvertuojamas į "1", todėl true
""      # false
"1"     # true
"00"    # true, nes ne "" ar "0"
"0.000" # true
undef   # traktuojama kaip "", todėl false
PERL'e naudojami sekantys sąlygos operatoriai: 
    1. if  
        2.  if/elsif  
        3.  unless
Operatorių  if  ir if/elsif sintaksės:

if (kontrolinė_išraiška) {			if (kontrolinė_išraiška_1) {
    true_statement_1;				    1_true_statement_1;
    true_statement_2;				    1_true_statement_2;
} else {					} elsif (kontrolinė_išraiška_2) {
    false_statement_1;				     2_true_statement_1;
    false_statement_2;				     2_true_statement_2;
}						} elsif (kontrolinė_išraiška_3) {
						     3_true_statement_1;
						     3_true_statement_2;
						} else {
    						     all_false_statement_1;
   						     all_false_statement_2;
						}

Šiuose operatoriuose else dalis yra nebūtina, o elsif dalis gali kartotis tiek kartų, kiek reikia. Pvz:
print "Kiek tau metų? ";
$a = <STDIN>;
chomp($a);
if ($a < 18) {
    print "Deja dar neturi balsavimo teisės...\n";
} else {
    print "Jus galite balsuoti!\n";
    $voter++; 
}
unless operatoriaus blokas  vykdomas tik tuomet, kai kontrolinės išraiškos reikšmė  yra false. 
elsif  ir else dalys yra nagrinėjamos tik tuo atveju, jei  kontrolinės išraiškos reikšmė yra true. 
unless(kontrolinė_išraiška_1) {
    1_false_statement_1;
    1_false_statement_2;
} elsif (kontrolinė_išraiška_2) {
    2_true_statement_1;
    2_true_statement_2;
  } else {
    all_false_statement_1;
    all_false_statement_2;
}
unless operatoriaus taikymo pavyzdys:
unless ($var >= 0) {
  print "Kintamasis \$var neigiamas \n";
} elsif ($var == 0) {
    print "Kintamasis \$var lygus nuliui \n";
} else {
    print "Kintamasis \$var teigiamas \n";
}

Operatoriai if  ir unless gali būti naudojami ir kaip modifikatoriai. Modifikatoriai keičia kintamojo reikšmę arba atlieka kitus veiksmus, jei patenkinama arba atitinkamai nepatenkinama kontrolinė sąlyga. Modifikatorių if  ir unless sintaksė:

   išraiška if kontrolinė_sąlyga
  išraiška unless kontrolinė_sąlyga

Modifikatorių taikymo pavydys:

$div = $var1/$var2 if $var2 != 0; 		#dalyba atliekama tik tuomet, kai $var2 nelygus 

Ciklo operatoriai

Nei viena programavimo kalba neišsiverčia be iteracinio skaičiavimo, kuris realizuojamas dėka ciklo operatorių. PERL naudojami tokie ciklo operatoriai: while, until, for, foreach.


while  /  until

Ciklo operatorius while  vykdys pakartotinai bloką tol, kol kontrolinės išraiškos reikšmė pasikeis į false. Šis ciklo operatorius naudojamas, kai iš anksto nežinomas iteracijų skaičius. Operatoriaus while sintaksė:

while (kontrolinė_išraiška) {
    statement_1;
    statement_2;
 }

Operatoriaus  while taikymo pavyzdys:

print "Kiek tau metu? ";
$a = <STDIN>;
chomp($a);
while ($a > 0) {
    print "Kazkada tau buvo $a metai...\n\t";
    system (sleep 1);
    $a--;
}

Kartais patogiau cikle kontrolinę sąlygą formuoti atvirkščiai nei operatoriuje while. Tuo atveju naudojamas ciklo operatorius until, kuriame blokas bus pakartotinai vykdomas, jei kontrolinė išraiška turės reikšmę false. Operatoriaus until sintaksė:

until (kontrolinė_išraiška) {
    statement_1;
    statement_2;
}

do {} while / untill

PERL'e naudojama ir ciklo operatorių  while/until atmaina do{}while/until, kurio sintaksė sekanti:

do {
    statement_1;
    statement_2;
    } while
kontrolinė_išraiška;

do{}until pavyzdys:

$stops = 0;
do {
    $stops++;
    print "Next stop? ";
    chomp($location = <STDIN>);
} until $stops > 5 || $location eq 'home';


for

Sekantis PERL ciklo operatorius for vykdomas lygiai taip, kaip ir C/C++ ar Java programavimo kalbose. Jis naudojamas, kai iš anksto žinomas arba lengvai suskaičiuojamas ciklo iteracijų skaičius. for sintaksė:

for ( initial_exp; test_exp; re-init_exp ) {
    statement_1;
    statement_2;
}

čia initial_exp - inicializacijos išraiška; test_exp - kontrolinės išraiška; re-init_exp - atnaujinanti išraiška (paprastai tai prieaugis).
Pavyzdys:

for ($i = 1; $i <= 10; $i++) {
    print "$i \n";
}


foreach

Kitas PERL ciklo operatorius foreach pritaikytas darbui su masyvais ar sarašais. Jis kintamajam $i paeiliui priskiria po vieną reikšmę iš sarašo @array ir vykdo bloke nurodytus veiksmus.  foreach sintaksė:

foreach $i (@array) {
    statement_1;
    statement_2;
}

Pavyzdžiai:

#
Maksimumo paieška                                               # Asoc. masyvo reikšmių išvedimas išrūšiavus pagal raktus
#! /usr/bin/perl -w                       #! /usr/bin/perl -w
@a = (1,2,3,4,5);                         %hash = (blue => 1, red => 2, green => 3);
$max = $a[0];                                  foreach (sort keys %hash) {
   foreach $b (@a) {                              print "$_ => $array{$_} \n;
     $max = $temp if $temp >$max; }            }
print "$max \n";


foreach ciklo operatoriaus kintamasis yra lokalus ir matomas tik ciklo viduje. Išėjus iš ciklo jis naikinamas ir nėra pasiekiamas! Panašiai kaip sąlygos taip ir ciklo operatoriai while until ir foreach gali būti modifikatoriais. Jų sintaksė:

išraiška while kontrolinė sąlyga;
išraiška until kontrolinė sąlyga;
išraiška foreach masyvas;

Cilko operatorių, veikiančių kaip modifikatoriai, pavyzdžiai:

$first = 10;
$second = 10;
@array = (1,2,3,4,5,6);
$first ++ while $first <15;                         #
$first didinamas iki 15
-- $second until $second <5;                        #
$second mažinamas iki 4

print
"$_\n"
foreach @array;                                           # išvedamos masyvo reikšmės


 

Ciklo valdymo komandos

Programose ciklo operatoriai baigia darbą tuomet, kai įvykdoma tam tikra sąlyga, pavyzdžiui operatoriaus while kontrolinė išraiška įgyja reikšmę false. Tačiau kartais egzistuoja situacijos, kai būtina anksčiau užbaigti ciklą, ar, pavyzdžiui, nepabaigus pilnos iteracijos pereiti prie naujos.

Tam tikslui yra naudojamos ciklo valdymo komandos last, next, redo. Jų sintaksė:

last žymės_identifikatorius;
next žymės_identifikatorius;
redo žymės_identifikatorius;

Žymės identifikatorius suprantamas kaip vardinio bloko žymė. Jei prie ciklo valdymo komandos žymės identifikatorius nenurodytas, tuomet laikoma, kad veiksmus reikia atlikti su giliausiai esančiu ciklu.

next
Ciklo valdymo komanda next nurodo, kad ciklo blokas su šia reikšme jau yra įvykdytas ir reikia pereiti prie sekančios iteracijos. Pavyzdžiui:

@array = (1,2,3,4,5,6);
foreach
(@array) {
next if $_ % 2;
print "$_\n";     
                                                                  #
atspausdinami tik nelyginai masyvo elementai
}


last
Ciklo valdymo komanda last nurodo, kad tai yra paskutinė ciklo iteracija ir programos valdymas perduodamas sekančiam po ciklo operatoriui, pavyzdžiui:

@letters = ("A" .. "Z");
for ($index = 0; $index < @letters; $index ++) {  
 # patikrinti kaip su
žinoti masyvo elementų skaičių.
last if $letters[$index] eq "M";
}

print $index;                                                                        #su
žinome kelinta abėcėlės raidė yra M


redo
Ciklo valdymo komanda redo pasako, kad ciklo iteraciją reikia dar kartą įvykdyti (pakartoti) su dabar esančiomis kintamųjų reikšmėmis.

$noempty =0;
$total = 0;
OUT: while (1)  {                                 
#uždėdami žymę, gauname vardinį bloką
    print "Iveskite ei
lute >";
    for ( ; ; )  {
          $ine = <STDIN>;
          chop ($line);
          last OUT if $line eq "END";
          ++ $total;
          redo OUT if $line eq "";
          ++ $noempty;
   }
}
print "Viso ivestos $total eilutes, is ju tuscios $noempty \n";


PERL kalbos sintaksė neturi daugiavariantinio sąlygos operatoriaus (switch operatoriaus analogo C/C++ kalboje). Tačiau panaudojus vardinius blokus ir aukščiau minėtas ciklų valdymo komandas, galima realizuoti struktūrinį algoritmą, veikiantį analogiškai kaip daugiavariantinis sąlygos operatorius. Pavyzdžiui:

#! /usr/bin/perl –w
$var = 3;
SWITCH: {
    $case1 = 1, last  SWITCH  if  $var == 1;
    $case2 = 1, last  SWITCH  if  $var == 2;
    $case2 = 1, last  SWITCH  if  $var == 3;
    $nothing = 1;
}


Besąlyginis perėjimo operatorius goto

Kaip ir daugelyje programavimo kalbų taip ir PERL yra naudojamas operatorius goto. Šis operatorius turi tris formas:

goto žymė;
goto išraiška;
goto &paprogram
ė;

Pirmuoju atveju operatorius goto perduoda programos valdymą tam tikram operatoriui praleidžiant dalį programos eilučių. Antruoju atveju kreipiamasi į tam tikrą išraišką ar reikšmę ir gražinama jos reikšmė. Trečiuoju atveju iškviečiama nurodyta paprogramė. Pavyzdys:

@label = (1, 2, 3);
goto $label[2];


Į turinį