Perli võrdlusoperaatorid. Perli skalaaride võrdlus. Phillips-peaga kruvikeeraja – lähtestage muutuja tingimuse alusel väärtusele ''

Vaadeldakse huvitavaid mitteilmseid Perli konstruktsioone.

Nagu teate, on Perli programmeerimiskeel väga väljendusrikas ja selle arsenalis on palju tööriistu, mis võimaldavad teil väljendada programmeerija kavatsusi koodis mitmel täiesti erineval viisil. Samuti võivad mõned operaatorite kombinatsioonid üsna keerulise süntaksi tõttu kaasa tuua huvitavaid efekte.

Samuti saab soovitud tulemuse saavutamiseks mõnda asja kasutada mittestandardsel viisil. Seda toimingut nimetatakse mõnikord "naelte tõmbamiseks mikroskoobiga". Täpselt seda me teemegi.

  • Selles artiklis esitatud väidete käitumine võib Perli versiooniti erineda.
  • Tõenäoliselt ei ole need operaatorid ette nähtud tootmises kasutamiseks.
  • Enamiku neist operaatoritest on loonud inimesed, kes naudivad oma lemmikkeele uurimist.
  • Kõik, mis allpool on toodud ja mida nimetatakse operaatoriteks, pole tegelikult nemad.

Operaator "Venus"

0+ +0

Nimi

Operaator sai oma nime välise sarnasuse tõttu Veenuse sümboliga.

Mida ta teeb?

Teisendab vasakul või paremal oleva argumendi, olenevalt versioonist, numbrikujuks. Näiteks:

Prindi 0+ "23a"; print 0+ "3.00"; print 0+ "1.2e3"; trükk 0+ "42 EUR"; print 0+ "kaks senti";

Tulemus:

23 3 1200 42 0

See operaator on venitus Saab kasutada oma projektides, kuid te ei tohiks unustada, et Perli seisukohast on näiteks numbrid: 0 aga tõsi 0E0 ja mõned keerulisemad konstandid. Veel tuleb märkida, et 0+ on vaikemeetod, mida kasutatakse numbrite teisendamiseks ülekoormuse kasutamisel.

"Kilpkonn", "vanker" või "Supermarketi käru"

@{}

Nimi

Operaator sai oma nime selle välise sarnasuse tõttu kilpkonna või jalutuskäruga. Märkimisväärne selle poolest, et Larry Wall avastas selle 1994. aastal.

Mida ta teeb?

See on nn konteinerite operaator, mis võimaldab stringi sees massiivi interpoleerida. Saadud massiivielemendid eraldatakse muutuja $" sisuga.

Kuidas see töötab?

Sisu on esmalt sunnitud hindama loendi kontekstis, seejärel eemaldatakse viide kohe (@( )).

Prindi "Testi i am @([ sure()])"; print "siin";

Tulemus:

Suri saidil demo.pl line 1.

Seda operaatorit saab kasutada suvalise koodi käivitamiseks stringides, kui toimub interpolatsioon. Näiteks saate seda kasutada mõne asja lihtsamaks muutmiseks, näiteks SQL-päringute koostamiseks:

My $sql = "SELECT id, nimi, palk FROM töötaja WHERE id IN (@([ võtmed % töötaja ])) SQL ";

kuid paarirealine koodivõit ei õigusta võimalikke turvaprobleeme (SQL-is on hea tava kasutada nn sidumismuutujaid, mis ettevalmistamise käigus asendatakse). Selle mitteilmsuse tõttu ei tasu tootmises operaatorit kasutada, seal on potentsiaalne haavatavus ja vähenenud loetavus.

Bang Bang

!!

Seda operaatorit kasutati siis, kui Perlit ei eksisteerinud; seda kasutasid sageli C-programmeerijad.

Kuidas see töötab?

See operaator teeb järgmist elementaarset asja - topelt eitus, mille olemus taandub Boole'i ​​teisendusele. Pidage meeles, et Perlis pole tõeväärtuslikke tüüpe.

Minu $true = !! "string"; minu $false = !! undef;

Selle tulemusena sisaldab $true 1 ja $false tühja stringi "" . Selle operaatori abil saab kontrollida, kas näiteks räsiviites on väärtus, nt.

!! $hash->(väärtus) või die("Väärtus puudub");

Uss

~~

Nimi?

See meenutab lihtsalt ja pretensioonitult ööliblika röövikut ja palju usse ka.

Kuidas see töötab?

Operaator ~~ näeb välja väga sarnane nutika sobitamisega, kuid mitte sellepärast, et see nii on ühetaoline operaator.

Unaartehte on ühe operandi tehe

Arukas sobitamine on aga kahendtehte (näiteks kahe operandi tehing, liitmine).

Mida ta teeb?

Lihtsalt skalaarmärksõna, mida on lühendatud nelja (!) tähemärgi võrra.

Perl -Esay~~kohalik aeg T 30. juuli 17:43:16 2013

Operaatori tööpõhimõte sarnaneb Bang Bangi (!!) operaatoriga, kuid erineb selle poolest, et Perlis on operaator sõltuv operaatorist. Lisateavet leiate Perli bitipõhiste toimingute dokumentatsioonist. Saate seda operaatorit kasutada, kuid peaksite olema ettevaatlik, pole teada, kuidas see kõigis Perli versioonides käitub.

Uss-pulgal

-~ ~-

See on kõrge prioriteediga suurendamise/vähendamise operaator. -~ suurendab ainult neid numbreid vähem null ja ~ - kahandab numbreid rohkem null

Selle operaatori prioriteetsus on suurem kui aritmeetilistel tehtetel, välja arvatud astendamine (**). Näiteks:

$y = ~-$x * 4;

See toimib identselt:

$y = ($x-1)*4;

Aga mitte nagu:

$y = ($x * 4) -1

Selleks, et need operaatorid töötaksid allkirjastamata andmetüüpidega, peate kasutama täisarvu pragmat (kasuta täisarvu). See operaator töötab üsna hästi ja seda saab tootmises kasutada, kuid te ei tohiks seda teha, sest mittestandardsete arhitektuuride puhul võib selle käitumine eeltoodust erineda. Tahaks seda ARM platvormidel töös proovida, aga artikli autoril sellist seadet pole.

Kosmosejaam

-+-

Avas Alistair McGlinchy 2005. aastal.

See operaator teostab kõrge prioriteediga ülekandmist numbrikujule ja sarnaneb käitumiselt Veenuse sümbolite operaatoriga, kuid erineb järgmistel viisidel. Veenuse operaator (0+ või +0) kasutab binaarne operaator + , samas kui "kosmosejaam" kasutab kolme ühendatud operaatorit ja seetõttu on sellel suurem prioriteet.

Samuti tasub meeles pidada, et sellel operaatoril on madalam prioriteet kui ühendatud operaatoritel * ja x . Selle tööpõhimõtteid saab illustreerida järgmise näitega, milles proovime numbriliseks teisendatud vormi “20GBP” kolm korda printida:

Vale, sest tagastab stringi "20GBP20GBP20GBP" teisendatud versiooni:

Prindi 0+ "20 GBP" x 3; # 20

Vale, sest samaväärne (print "20") x 3:

Prindi (0+ "20 GBP") x 3; # 20

Õige, aga väga pikk, väga Lisp-lik:

Prindi((0 + "20 GBP") x 3); #202020

Täpselt nii – kasutades operaatorit "Space Station":

Prindi -+- "20GBP" x 3; #202020

Siiski, kuna unary miinus - ja unary + lihtsalt asendage stringi tulemus selle väärtusega, siis see operaator ei tee Töötage järgmist tüüpi stringidega:

  • Nendega, mis algavad tähega - .
  • Nendega, mis algavad mitte numbriline sümbol.

Veenuse operaator töötab kõigil neil juhtudel, kuid sellel on madalam prioriteet.

Kitse või Saturni operaator

=()=

Mida ta teeb?

See operaator tutvustab loendi konteksti sellest paremal ja tagastab elementide arvu vasakule.

Kuidas see töötab?

Skalaarses kontekstis olev loend tagastab elementide arvu. Pole tähtis, mitu elementi neist muutujatele omistati. Sellisel juhul kantakse avaldise parem pool tühja nimekirja ja seejärel visatakse see kõrvale.

$n =()= /sõna1|sõna2|sõna3/g; $n =()= "abababab" =~ /a/; # $n = 1 $n =()= "abababab" =~ /a/g; # $n = 4

Lisaks on selleks operaatoriks konteiner (!), mis võimaldab hõlpsalt parema poole tulemuse sinna sisse tõmmata. See tähendab, et saame teha järgmist:

$n =($b)= "abababab" =~ /a/g; # $n = 4; $b = "a" $n =(@c)= "abababab" =~ /a/g; # $n = 4; @c = qw(a a a a)

Järgmisel "kaval" näitel selle kasutamisest näib olevat kasu, kuid on veel üks salajane operaator, kes suudab sama teha.

Oletame, et tahame teada, mitmeks osaks jagamine jagab stringi, kuid meid ei huvita elemendid ise, võib-olla on mõttekas proovida midagi sellist:

Minu $count = split /:/, $string;

See näide tagastab meile vajaliku arvu, kuid vannub:

Kaudse jaotuse kasutamine @_ jaoks on aegunud

Selle probleemi lahendamiseks saame kasutada seda operaatorit ja kirjutada midagi sellist:

Minu $count =()= split /:/, $string;

Mis ei anna hoiatust, kuid tagastab alati 1, kuna jaguneb mitte kunagi ei jaga nööri rohkemaks osaks kui vaja. Kompilaator omakorda käsitleb ()-sse salvestamise katset väitena, et me ei vaja neid elemente ja tagastab muutumatu stringi, mis taandatakse ühe elemendiga loendiks.

Võimalikke lahendusi on kaks.

Esimene on see, et saame takistada kompilaatoril split() optimeerimist, määrates -1-ga, et tahame lõpmatu arvu stringi tükke:

Minu $count =()= split /:/, $string, -1;

Või kasutage mõnda muud salajast operaatorit "kilpkonn":

Minu $count = @([ split /:/, $string ]);

lohe

~~<>

Tegelikult on see operaator lihtsalt kombinatsioon Wormi ja<>. See annab readline() operatsioonile skalaarse konteksti, kuid see on kasulik ainult loendi kontekstis.

Kaunistatud kahe teraga mõõk

<> m ;

See salajane operaator pakub mitmerealisi kommentaare ja ei midagi muud. Kasutusnäide:

<> Kasutage salajast operaatorit eelmisel real. Pane oma kommentaarid siia. Palju-palju kommentaare. Võite kasutada isegi tühje ridu. Lõpeta ühe m-ga;

Kuid peaksite arvestama tõsiasjaga, et see kommentaar on lihtsalt topeltjutumärkides olev string ja seetõttu võib sellel olla mõningaid kõrvalmõjusid.

Kruvikeerajad

Avastas Dmitri Karasik, otsides operaatoreid põhjal! . Nagu kruvikeerajad, on ka neid operaatoreid nelja peamist tüüpi, kuid erineva käepideme pikkusega:

Sirge kruvikeeraja - vähendab vastavalt seisundile:

$x -=!! $y # $x-- kui $y; $x -=! $y # $x-- välja arvatud juhul, kui $y;

Phillipsi kruvikeeraja – juurdekasv vastavalt seisundile:

$x +=!! $y; # $x++, kui $y; $x +=! $y; # $x++ kui just $y;

Star kruvikeeraja - lähtestage muutuja 0-le vastavalt tingimusele:

$x *=!! $y; # $x = 0, välja arvatud juhul, kui $y; $x *=! $y; # $x = 0, kui $y;

Phillipsi piluga kruvikeeraja – lähtestage muutuja tingimuse järgi väärtusele '':

$x x=!! $y; # $x = "", välja arvatud juhul, kui $y; $x x=! $y; # $x = "", kui $y;

Ettevõtte operaator

()x!!

Üsna sageli tekib vajadus mõne tingimuse alusel loendisse lisada element. Seda saab teha järgmiselt.

Minu @ostunimekiri = ("leib", "piim"); push @shopping_list, "õunad", kui $kapp(õunad)< 2; push @shopping_list, "bananas" if $cupboard{bananas} < 2; push @shopping_list, "cherries" if $cupboard{cherries} < 20; push @shopping_list, "tonic" if $cupboard{gin};

Selles osas räägime tingimuslausetest ja tsüklitest.

Tingimuslikud väited

Nagu ikka, alustame kohe näidetega.

$a = nihe ;
kui ($a > 10) (
print "a > 10 \n";
}

See konstruktsioon peaks C-tüüpi keeltes programmeerijatele valusalt tuttav olema, nii et siin pole palju kommenteerida. Lubage mul lihtsalt öelda, et erinevalt C-st ei saa te siin lokkis traksid ära jätta. Täpsemalt, viis on olemas, aga sellest lähemalt allpool. Konstruktsioonid if-else ja if-else-if-… Perlis näevad välja järgmised:

$a = nihe ;
kui ($a > 10) (
print "a > 10 \n";
) muidu (
print "a<= 10\n";
}

kui ($a > 0 ) (
# tee midagi
) elsif ($a == 0 ) (
# tee midagi
) muidu (
# tee midagi muud
}

Üldiselt on kõik ootuspärane, välja arvatud üks erand. Perlis pole "muu kui" - selle asemel tuleks kasutada elsifi ja ainult seda. Elsifi saab korrata mitu korda, muidu pole vaja ja lokkis trakse ei saa ära jätta.

Erinevalt teistest programmeerimiskeeltest pakub Perl ka lauset, kui pole. Järgmised kaks koodiosa teevad sama:

välja arvatud juhul, kui ($a == 0 ) (
# "...kui a ei ole null"
...
}

if ($a != 0) (
# sama
# ...
}

Välja arvatud juhul, kui seda saab kasutada koos elsifi ja muuga, kuid Perlis pole "elsunlessi".

Perlil on võimalus koodi hulka vähendada, kui tingimuse täitmisel on vaja käivitada ainult üks koodirida. Järgmised näited teevad sama.


kui ($a > $b) (
väljapääs 1;
}


kui just ($b == $c ) (
väljapääs 2 ;
}

# kui tingimus on tõene, lõpetage skript koodiga 1
exit 1 if ($a > $b) ;
# kui b == c, jätkake skripti täitmist
välju 2, kui ($b == $c ) ;

Siiski ei pea te viimases näites sulgusid kasutama:

# kui tingimus on tõene, lõpetage skript koodiga 1
välju 1, kui $a > $b ;

Kui kirjutate Java/PHP või mõnes muus C-laadses keeles, on see konstruktsioon teie jaoks tõenäoliselt ebatavaline, kuid praktikas on see tõesti mugav. Vene keeles ütleme tavaliselt ka "lõpetage programm, kui ...", mitte "kui ... siis ...".

Nii nagu C/C++ ja PHP, on ka Perlil kolmekordne operaator?:. See töötab sarnaselt if-else konstruktsiooniga, ainult avaldiste sees:

kui ($a > $b) (
$a = $a / $b ;
) muidu (
$a = $b / $a ;
}

# sarnane kood, kasutades küsimärgioperaatorit
# üks koodirida viie asemel
$a = $a > $b ? $a / $b: $b / $a ;

Ütleksin paar sõna ka võrdlusoperaatorite kohta. Võrdlusoperaatorid Perli keeles jagunevad need kahte rühma – need, mis võrdlevad numbreid ja stringe.

Nagu mäletate, saab Perli skalaare tõlgendada kas stringide või numbritena. Näiteks arv 123 on suurem kui arv 45, kuid string "123" on väiksem kui string "45". Selleks oli vaja mitut võrdlusoperaatorite rühma. Stringide võrdlemine Perlis toimub samamoodi nagu teistes kaasaegsetes programmeerimiskeeltes, seega loodan, et see küsimusi ei tekita.

Silmused, foreach, while/until, do..while/until

For-silmus on kõigile programmeerijatele väga tuttav:

# printige string "0 1 2 3 4"
jaoks ($i = 0; $i< 5 ; $i ++ ) {
print "$i" ;
}

Järgnev on kirjutatud semikooloniga eraldatud sulgudes:

  1. Kood käivitati enne tsükli algust.
  2. Seisukord testimisel enne algust(ja mitte lõpus, nagu paljud inimesed arvavad) iga iteratsiooni kohta. Kui see on vale, siis silmus lõpeb.
  3. Kood käivitatakse pärast iga iteratsiooni.

Nagu tingimuslausete puhul, ei saa tsüklites välja jätta lokkis sulgusid (selleks on ka spetsiaalne märge – vt allpool).

Foreach peaks olema PHP programmeerijatele väga tuttav:

@arr = (0, 1, 2, 3, 4);
# printige string "0 1 2 3 4"
foreach $i (@arr ) (
print "$i" ;
}

Foreach-tsükli kehaosa täidetakse iga sulgudes määratud massiivi elemendi jaoks. Foreachi oluline tunnus on muutujas $i pole kopeeritud massiivi element @arr, nagu paljud arvavad. Muutuja $i tsükli kehas on massiivi element ise. Seega suurendab järgmine kood massiivi @arr iga elemendi väärtust ühe võrra:

$i = 19880508;
foreach $i (@arr ) (
$i++;
}
# $i on endiselt 19880508

foreach’i saab kasutada ka räsidega töötamiseks:

% hash = (
aaa => 1,
bbb => 2,
) ;
# võtmete funktsioon tagastab massiivi, mis sisaldab kõiki räsivõtmeid
foreach $k (klahvid %hash ) (
print "$k => $hash($k) \n";
}

Perlis on foreach-silmusel lühike vorm:

# kui unustasite, mida qw-operaator teeb,
# minge tagasi "Perli programmeerimise põhitõdede" esimese osa juurde
$i eest (qw/1 2 3/ ) (
print "$i" ;
}

See tähendab, et praktiliselt kõikjal saate foreachi asemel lihtsalt kirjutada. Perl ei aja seda päris for-tsükliga segi, sest viimane nõuab semikooloneid ja nii edasi.

Silmused While, till ja do töötavad täpselt samamoodi nagu C++ või Pascal/Delphi puhul:

# printige "1 2 3 4 5" neljal erineval viisil

$i = 0;
samas ($i< 5 ) { # seni, kuni $i on väiksem kui viis
print ++ $i . "" ;
}
printida" \n"; # uus rida

$i = 0;
kuni ($i == 5 ) ( # kuni $i võrdub viiega
print ++ $i . "" ;
}
printida" \n";

$i = 0;
teha (
print ++ $i . "" ;
) while ($i< 5 ) ; # kontroll tsükli lõpus
printida" \n";

$i = 0;
teha (
print ++ $i . "" ;
) kuni ($i == 5 ) ;
printida" \n";

Analoogiliselt if- ja ei-lausetega on olemas lühendatud kirjutamistsüklite vorm:

$i = 0;
print ++ $i . " " while ($i< 5 ) ;
printida" \n";

$i = 0;
print ++ $i . " " kuni ($i == 5 ) ;
printida" \n";

print "$_" jaoks (qw/1 2 3 4 5/ ) ; # võid ka foreach(qw/1 2 3 4 5/);
printida" \n";

Pange tähele viimast foreach-silmust. Me mäletame, et see on foreachi stenogramm, mitte foreach, eks? Viimasel, muide, puudub lühike sissekanne. Seega ei täpsustatud siin muutuja nime, millega massiivi elementidele juurde pääseme. Seda ei saa kasutada stenogrammi eessõnas. Sel juhul kasutatakse spetsiaalset muutujat - $_. Ka järgmine näide on üsna toimiv:

jaoks (qw/1 2 3 4/ ) (
print "$_" ;
}

Muide, selle saab ümber kirjutada järgmiselt.

6.5.1. Lihtsad operaatorid

Lihtne operaator PERL-is on see avaldis, millel võib olla üks modifikaator. Iga lihtlause ees peab olema semikoolon, välja arvatud juhul, kui see on ploki viimane lause; sel juhul võib semikooloni ära jätta. Seal on viis lihtsat operaatori modifikaatorit:

$count = 5; print "$count\n", kui $count; print "$count\n", samas kui $count--; @inimesed = qw/Anna Boris Victor/; print "$_\n" foreach @people;

Saame rakendada modifikaatoreid mitte ainult lihtsatele lausetele, vaid ka plokkidele. Selleks tuleb ploki ette panna märksõna teha:

Do ( $rida = ; ... ) kuni $ line eq ".\n";

Selline plokk käivitatakse alati vähemalt üks kord enne tingimuse kontrollimist. Pange tähele, et tsükli juhtlaused sellistes konstruktsioonides ei tööta, kuna modifikaatoritel pole silte.

Disain teha BLOKKI(ilma modifikaatorita) kasutatakse ka PERL-is: see võimaldab teil muuta ploki avaldisteks ja tagastab selle ploki viimase lause väärtuse.

6.5.2. Liitoperaatorid

Liitoperaatorid koosneb plokid, suletud lokkis traksidega. Tuletage meelde, et erinevalt C-st või Java-st on liitlausetes nõutavad lokkis sulud, isegi kui need sisaldavad ainult ühte lauset. PERL sisaldab järgmisi liitlauseid:

6.5.2.1. Tingimuslik kui avaldus

Tingimuslik operaator kui võimaldab teil kontrollida teatud tingimust ja sõltuvalt selle tõesusest käivitada teatud operaatorite jada. Sellel on järgmised vormid:

kui (väljendus) PLOKKI1 kui (väljendus) PLOKKI1 muidu PLOK2 kui (väljend1) PLOKKI1 elsif (väljend2) PLOK2 ... muidu BLOCKn

väljendus tõsi, siis tõsi PLOKKI1; kui see on vale, antakse juhtimine üle järgmisele operaatorile kui.

väljendus tõsi, siis tõsi PLOKKI1; kui see on vale, siis see täidetakse PLOK2.

Kolmas operaatori vorm tähendab, et kui väljendus tõsi, siis tõsi PLOKKI1; kui see on vale ja tõsi väljend2, siis on see täidetud PLOK2 jne. Kui avaldised operaatori kõigis harudes on valed, siis BLOCKn.

Järgmises näites määratakse muutuja $m suurimale kolmest arvust $x , $y , $z :

Kui ($x >= $y) ( $m = ($x >= $z) ? $x: $z; ) else ( $m = ($y >= $z) ? $y: $z; )

6.5.2.2. Tingimuslik avaldus, välja arvatud juhul

Tingimuslik operaator kui ei kui. Sellel on kaks vormi:

kui ei (väljendus) PLOKKI1 kui ei (väljendus) PLOKKI1 muidu PLOK2

Operaatori esimene vorm tähendab, et kui väljendus vale, siis hukati PLOKKI1; kui see on tõsi, antakse juhtimine üle järgmisele operaatorile kui ei.

Operaatori teine ​​vorm tähendab, et kui väljendus vale, siis hukati PLOKKI1; kui see on tõsi, siis täidetakse PLOK2.

Eelmise näite saab ümber kirjutada järgmiselt:

Kui just ($x< $y) { $m = ($x >= $z) ? $x: $z; ) else ( $m = ($y >= $z) ? $y: $z; )

6.5.2.3. Kuigi silmuse operaator

Silmusoperaator samas sellel on kaks vormi:

samas (väljendus) BLOKKI samas (väljendus) BLOKKI jätka PLOKKI1

Operaator samas

  1. Väärtus arvutatakse väljendid
  2. Esitatud BLOKKI.
  3. jätka, siis on see täidetud PLOKKI1.

$i = 0; while ($i++< 10) { print "$i\n" }

Kasutades operaatori teist vormi samas, selle saab kirjutada nii:

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

Seda operaatorit kasutades peate selles varem või hiljem veenduma väljendus muutub valeks, sest muidu siseneb programm lõpmatusse tsüklisse, näiteks:

Kuigi (1) ( prindi "Tere kõigile!" )

6.5.2.4. Kuni silmuse operaatorini

Silmusoperaator kuni loogiliselt vastupidine operaatorile samas ja sellel on ka kaks vormi:

kuni (väljendus) BLOKKI kuni (väljendus) BLOKKI jätka PLOKKI1

Operaator kuni tehakse järgmiselt:

  1. Väärtus arvutatakse väljendid. Kui see on tõene, antakse juhtimine üle sellele väitele järgnevale väitele.
  2. Esitatud BLOKKI.
  3. Kui avaldus sisaldab märksõna jätka, siis on see täidetud PLOKKI1.
  4. Juhtimine viiakse üle 1. etappi.

Järgmine näide näitab numbreid ühest kümneni:

$i = 1; kuni ($i > 10) ( prindi "$i\n" ) jätka ( $i++ )

6.5.2.5. For silmuse operaator

Silmusoperaator jaoks on kujul:

jaoks (initsialiseerimine; tingimus; muuta) BLOKKI

Operaator jaoks tehakse järgmiselt:

  1. Avaldus täidetakse initsialiseerimine(tavaliselt lähtestab see tsükliloenduri või loendurid).
  2. Avaldise väärtus arvutatakse tingimus. Kui see on vale, antakse juhtimine üle sellele operaatorile järgnevale operaatorile.
  3. Esitatud BLOKKI.
  4. Avaldus täidetakse muuta(tavaliselt suurendab või vähendab see tsükliloendurit või loendureid) ja juhtimine viiakse üle 2. etappi.

Seda operaatorit kasutatakse tavaliselt juhtudel, kui tsükli korduste arv on ette teada. Seega võiksime eelmise näite kirjutada lühemalt:

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

6.5.2.6. Iteratsioonioperaator foreach

Operaator igaühele teeb loendi või massiivi iga elemendi jaoks määratud toiminguid. Sellel on kaks vormi:

igaühele muutuv (nimekirja) BLOKKI igaühele muutuv (nimekirja) BLOKKI jätka PLOKKI1

Operaator igaühele tehakse järgmiselt:

  1. Muutuv määratud järgmisele elemendile nimekirja. Kui nimekiri on ammendunud, antakse juhtimine üle antud operaatorile.
  2. Esitatud BLOKKI.
  3. Kui avaldus sisaldab märksõna jätka, siis on see täidetud PLOKKI1.
  4. Juhtimine viiakse üle 1. etappi.

Toome sama näite numbrite trükkimisel 1 kuni 10:

Foreach $i (1..10) ( prindi "$i\n" )

Muutuv on antud operaatori jaoks lokaalne, st pärast iteratsiooni lõppu taastatakse selle eelmine väärtus. Kui panete märksõna muutuja ette minu, siis on see leksikaalselt piiratud operaatori kehaga. Kui muutuv jäetakse välja, kasutatakse erilist muutujat $_:

Foreach (1..10) ( prindi "$_\n" )

Kui üks elementidest nimekirja on massiiv, siis ei tohiks tsükli põhiosa seda muuta, vastasel juhul on tulemused ettearvamatud.

Tegelikult operaatorid jaoks Ja igaühele on sünonüümid ja võite kasutada ükskõik millist neist sõnadest, kui soovite.

6.5.2.7. Operaatori sildid

Operaatoritele samas, kuni, jaoks Ja igaühele, ja saab asetada ka plokkide ette sildid. Märgitud operaatoril on vorm:

silt: operaator

Sildiks võib olla mis tahes identifikaator, mis ei ole reserveeritud sõna, kuid PERL-is on tavaks kirjutada sildid suurtähtedega.

Kuigi tänapäevases programmeerimises peetakse siltide kasutamist halvaks vormiks, lihtsustab nende kasutamine mõnel juhul oluliselt programmi loogikat. See juhtub kõige sagedamini siis, kui silte kasutatakse juhtimise ülekandmiseks sügavalt pesastatud ahelalt välisele ahelale. Vaatleme järgmist näidet, mis on kirjutatud C++ parimate traditsioonide kohaselt:

Sest (minu $i = 0; $i< @ary1; $i++) { for (my $j = 0; $j < @ary2; $j++) { if ($ary1[$i] >$ary2[$j]) ( viimane; ) $ary1[$i] += $ary2[$j]; ) )

Sildid ja silmusjuhtimisoperaatorid võimaldavad teil selle algoritmi kirjutada palju lühemalt ja mis kõige tähtsam, palju läbipaistvamalt:

VÄLIS: minu $x (@ary1) jaoks ( minu $y jaoks (@ary2) (järgmine VÄLINE, kui $x > $y; $x += $y; ) )

6.5.2.8. viimane operaator

Operaator viimane lõpetab kohe määratud tsükli. Sellel on kaks vormi:

viimane silt viimane

Operaatori esimene vorm lõpetab tsükli etteantuga silt. Teine vorm lõpetab praegu töötava sisemise pesastatud tsükli täitmise. Kui silmusel on plokk jätka, siis seda ei täideta. Näide:

LINE: samas ( ) ( viimane RIDA, kui /^$/; # katkestage silmus, kui tekib tühi rida... )

6.5.2.9. järgmine operaator

Operaator järgmiseks alustab määratud tsükli uut iteratsiooni. Sellel on kaks vormi:

järgmiseks silt järgmiseks

silt jätka, siis käivitatakse see enne uue iteratsiooni algust. Näide:

LINE: samas ( ) ( järgmine rida, kui /^#/; # jäta kommentaarid vahele... )

6.5.2.10. uuesti operaator

Operaator uuesti teha alustab määratud tsükli uut iteratsiooni ilma selle täitmise tingimust kontrollimata. Sellel on kaks vormi:

uuesti teha silt uuesti teha

Operaatori esimene vorm alustab antud tsükli uut iteratsiooni silt. Teine vorm alustab praegu töötava sisemise pesastatud tsükli uut iteratsiooni. Kui silmusel on plokk jätka, siis seda ei täideta. Järgmises näites eemaldatakse Pascali programmist kommentaarid, kui need on kujul () (näide on lihtsustatud, kuna see ei võta arvesse, et stringikonstandid võivad sisaldada () märke):

LINE: samas ( ) ( while (s|((.*).*)(.*)|$1 |) () s|(.*)| |; if (s|(.*| |) ( $front = $_; samal ajal ( ) ( if (/)/) ( s|^|$front\(|; tee uuesti LINE; ) ) ) print; )

6.5.2.11. Blokk kui degenereerunud tsükkel

Plokki käsitletakse PERL-is tsüklina, mis täidetakse tingimusteta üks kord. See tähendab, et saame konstruktsiooni kasutada

PLOKKI1 jätka PLOK2

mis tavaliselt tähendab, et see töötab PLOKKI1, ja pärast seda PLOK2. Plokkide käsitlemine tsüklitena tähendab aga ka seda, et saame plokkide sees kasutada tsükli juhtlauseid, mille puhul see konstruktsioon muutub väga kasulikuks.

Üks põhjusi, miks PERL ei sisalda Select-lauset lüliti, on see, et plokkide ja silmusjuhtlausete abil on väga lihtne modelleerida, näiteks:

LÜLITUS: ( $abc = 1, viimane LÜLITUS, kui /^abc/; $def = 1, viimane LÜLITUS, kui /^def/; $xyz = 1, viimane LÜLITUS, kui /^xyz/; $ midagi = 1; )

6.5.2.12. goto operaator

PERL sisaldab hüppeoperaatorit minema kolm tüüpi:

minema silt minema väljendus minema &Nimi

Operaatori esimene vorm annab juhtimise üle operaatorile koos määratud silt. Juhtimist ei saa üle kanda lähtestamist nõudva struktuuri sees, näiteks alamprogrammi või lause sees igaühele.

Teine vorm on "arvutatav" minema": see arvutab väärtuse väljendid ja annab juhtimise üle saadud sildile, näiteks:

Goto("LABEL1", "SILT2", "SILT3")[$i];

Kolmas vorm ei ole üldse minema selle sõna tavalises tähenduses. See operaator asendab alamprogrammi kõne Nimi praegu töötava alamprogrammi asemel. Seda kasutavad AUTOLOAD() rutiinid, mis soovivad vaikselt asendada ühe rutiini kutse teisega. Nimi ei pea olema alamprogrammi nimi; see võib olla skalaarmuutuja või plokk, mille väärtus on viide alamprogrammile.

Lisaks põhjalikule stringide võrdlusoperaatorite loendile lisab Sinan Ünür Perl 5.10 nutika vaste operaatori.

Nutika vaste operaator võrdleb kahte elementi nende tüübi alusel. Vaadake allolevat diagrammi 5.10 käitumise kohta (ma usun, et see käitumine muutub 5.10.1 puhul veidi):

perldoc perlsyn "Nutikas sobitamine üksikasjalikult":

Nutika sobitamise käitumine sõltub sellest, millised on argumendid. See on alati kommutatiivne, st. $a ~~ $b käitub samamoodi nagu $b ~~ $a . Käitumise määrab järgmine tabel: Esimene rida, mida rakendatakse suvalises järjekorras, määrab vaste käitumise.

$a $b Vaste tüüp Kaudne sobituskood ====== ===== ======= ======== ===== (ülekoormamine võidab kõik) Kood[+] Kood[+] viitevõrdsus $a == $b Suvaline kood[+] skalaarne alamtõde $b−>($a) Räsi Räsi räsivõtmed identsed ~~ Räsimassiivi räsilõike olemasolu grep (olemas $a−>($_ )) @$b Räsi Regexi räsivõti grep grep /$b/, võtmed %$a Räsi Kõik räsikirjed on olemas $a−>($b) Massiivi massiivid on identsed[*] Massiivi Regex massiivi grep grep /$b * ~ /$b/ Code() Code() tulemused on võrdsed $a−>() eq $b−>() Suvaline kood() lihtne sulgemistõde $b −>() # ignoreerides $a Num numish[!] numbriline võrdsus $a == $b Suvaline stringi võrdsus $a eq $b Suvaline arv numbriline võrdus $a == $b Iga mis tahes stringi võrdsus $a eq $b + − see peab olema koodiviide, mille prototüüp (kui see on olemas) mitte "" ("" prototüübiga alamühikuid käsitleb allpool kirje "Code()") * - see tähendab, et iga element vastab sama indeksi elemendile teises massiivis. Kui leitakse ringviide, pöördume tagasi referentsiaalse võrdsuse juurde. ! − kas reaalarv või string, mis näeb välja nagu arv

Muidugi ei ole "vastavuskood" tegelik vastekood: see lihtsalt selgitab kavandatud tähendust. Erinevalt grepist loob nutika vaste operaator võimaluse korral silmuse.

Kohandatud kaardistamine ülekoormuse kaudu Saate muuta seda, kuidas objekti kaardistatakse, koormates üle operaatori ~~. See on parem kui tavaline nutikas sobitamise semantika. Vaadake ülekoormust.

Skalaarsete andmete või skalaarmuutujate väärtuste võrdlemiseks pakub Perl binaarsete operaatorite komplekti, mis hindavad oma operandide vahelisi võrdsussuhteid, suuremaid, suuremaid või võrdseid jne seoseid, mistõttu seda operaatorite rühma nimetatakse ka nn. relatsioonioperaatorid. Perl kasutab arvandmete ja stringandmete võrdlemiseks erinevaid operatsioone. Kõik need on esitatud tabelis. 4.1.

Tabel 4.1. Suhteoperatsioonid

Operatsioon Numbriline String Tähendus
Võrdsus == ekv Tõene, kui operandid on võrdsed, väära muidu
Ebavõrdsus != ne Tõene, kui operandid ei ole võrdsed, väära muidu
Vähem < lt Tõene, kui vasak operandi väärtus on väiksem kui parem, vastasel juhul väär
Rohkem > GT Tõene, kui vasak operand on suurem kui parem, muul juhul väär
Vähem või võrdne <= le Tõene, kui vasak operandi väärtus on suurem või võrdne parempoolse operandiga, muul juhul väär
Enam või võrdne >= ge Tõene, kui parem operand on suurem või võrdne vasakpoolse operandiga, muul juhul väär
Võrdlus <=> cmt 0, kui operandid on võrdsed
1, kui vasak operand on suurem kui parem operand
-1, kui parem operand on suurem kui vasak

Relatsioonioperatsioonide tulemus (v.a viimane võrdlus) on Tõene, väärtus 1 või Väär, tühi string "".

Kommenteeri
Väärtust true aritmeetilistes operatsioonides tõlgendatakse kui arvu 1 ja stringitehetes kui stringi "1". Väärtust false tõlgendatakse aritmeetilistes operatsioonides arvuna 0 ja stringitoimingutes tühja stringina " ".

Numbrilised relatsioonitehted

Numbrilise seose operatsioone rakendatakse arvandmetele, kus ühte või mõlemat operandi saab määrata stringiga, mis sisaldab kehtivat kümnendarvu. Kui numbriliste relatsioonioperatsioonide puhul on operandi määratud stringiga, mille sisu ei esinda kehtivat kümnendarvu, määratakse selle väärtuseks o ja kuvatakse hoiatus, mis näitab, et operandi ei kasutata numbrilises relatsioonioperatsioonis õigesti (kui Perli hoiatusrežiim on lubatud). Arvandmete relatsioonitehte tähendus vastab tavapärastele arvude võrdlemise matemaatilistele tehtetele (näide 4.7).

123 > 89; # Tulemus: 1 (tõene)

123 < 89; # Результат: "" (ложь)

123 <= 89; # Результат: "" (ложь)

89 <= 89; # Результат: 1 (истина)

23 >= 89; # Tulemus: "" (vale)

23 <=>89; # Tulemus: -1 (parem operand on suurem kui vasak)

89 <=>23; # Tulemus: 1 (parem operand on suurem kui vasak operand)

Numbriliste võrdlustoimingute kasutamine ei ole keeruline, kuid kümnendkohtade ujukomaarvude võrdsuse võrdlemisel võivad ilmneda ümardamisefektid, kuna reaalarvude mantissis on piiratud arvu olulisi numbreid arvutis ja see toob kaasa " vale” võrdlustoimingute toimimine kasutaja vaatevinklist . Näide 4.8 illustreerib sarnast olukorda.

#! peri -w
$z = 0,7;

$zz = 10+0,7-10; # Muutuja $zz sisaldab arvu 0,7

# Trüki string "z võrdub zz", kui muutujate $z ja $zz väärtused on võrdsed print "z võrdub zz\n", kui ($z == $zz);

Kui proovime käivitada näidet 4.8, avastame üllatusega, et meie programm ei prindi midagi. Mis viga? Lahendus peitub operaatoris muutuja $zz väärtuse arvutamiseks. Aritmeetiliste toimingute tegemisel annavad ümardamisvead tulemuseks väärtuse 0,699999999999999 (saate sisestada $zz muutuja print lause ja seda kontrollida), kuigi see on 0,7 lähedal, ei ole see sellega täpselt võrdne. Seetõttu töötas võrdlusoperatsioon õigesti!

Nõuanne
Ärge kasutage võrdlusoperaatorit reaalarvude võrdsuseks, selle tulemus ei pruugi vastata sellele, mida matemaatikast vaadatuna eeldatakse. Kui teil on vaja kontrollida kahe reaalarvu võrdsust, on parem võrrelda nende erinevuse absoluutväärtust mõne väga väikese arvuga (olenevalt nõutavast täpsusest):

kõhulihased ($a-$b)<= 0.00000001; # Проверка равенства

Stringi relatsioonioperatsioonid

Stringiandmete võrdlus põhineb nende järjestamisel ASCII kooditabeli järgi, st madalama ASCII koodiga märk eelneb kõrgema ASCII koodiga märgile. Stringide võrdlemine toimub tähemärgi haaval vasakult paremale. See tähendab, et kui ridade esimesed märgid on võrdsed, siis võrreldakse teisi ja kui need on võrdsed, siis kolmandaid jne. Veelgi enam, kui read on erineva pikkusega, siis märkide arv lühema pikkusega rea ​​lõppu lisatakse võrdsuse jaoks puuduv kood o. Tuleb märkida, et erinevalt mõnest teisest programmeerimiskeelest on Perlis stringide võrdlemisel olulised lõpumärgid. Näide 4.9 näitab stringide võrdlusi, mis illustreerivad kirjeldatud reegleid.

"A" See "a"; # Tulemus: tõene (kood "A" on \101, kood "a" on \141)
"a" See "aa";
# koodiga \000, mis on väiksem kui kood \141
# parempoolse operandi stringi teine ​​märk "a")
"a" See "a"; # Tulemus: tõene (märk lisatakse stringile "a"
# koodiga \000, mis on väiksem kui kood \040
# parempoolse operandi stringi lõppruum)
"12" See "9"; # Tulemus: tõene (kood "1" - \061, kood "9" - \071)
"9" võrdne 09"; # Tulemus: vale (kood " " - \040, kood "O" - \060)

Pöörame tähelepanu stringiliteraalide kahele viimasele võrdlusoperatsioonile. Nende operandide sisu saab teisendada õigeteks arvudeks ja seetõttu kehtivad neile sarnased numbrilised relatsioonitehted. Nende tulemus erineb aga oluliselt stringirelatsioonitoimingute tulemusest. Operatsiooni kasutamisel< в предпоследнем выражении результат будет Ложь, а если в последнем выражении применить операцию ==, то результат будет Истина. Об этом всегда следует помнить, так как Perl автоматически преобразует символьные данные в числовые там, где это необходимо.