Felhasználói eszközök

Eszközök a webhelyen


st-linux_alapok:fejezetek:ciklusok

Ciklusok

Ciklust akkor alkalmazunk, ha egy műveletet vagy műveletsort többször kell végrehajtani. Shell szkriptekben a for, a while és az until ciklusokat is alkalmazhatjuk.

A for ciklus

A for ciklust akkor alkalmazzuk, ha pontosan tudjuk, hányszor kell végrehajtani az adott műveletsorozatot. Az alábbi egyszerű szkript az i változónak ad 1, 3, 5, 7, 9 értékeket és végrehajtja a do és done kulcsszavak közötti parancsokat. Értelemszerűen annyiszor hajtja végre ahány elem van a felsorolásban:

#!/bin/bash
for i in 1 3 5 7 9
do
echo "$i a négyzeten = `expr $i '*' $i`"
done

A do és a done közötti sorokat ciklusmagnak is nevezzük.

palferi@lizi:~/proba$ ./c1.sc 
1 a négyzeten = 1
3 a négyzeten = 9
5 a négyzeten = 25
7 a négyzeten = 49
9 a négyzeten = 81

A lista helyett bármilyen parancsot is írhatunk aminek a kimenete fog listát meghatározni. Gyakran alkalmazzák a seq (sequence, sorozat) parancsot:

for i in `seq 1 3 25`
do
echo "$i a négyzeten = `expr $i '*' $i`"
done

Itt a seq 1 3 25 parancs egytől huszonötig listát hoz létre hármas lépéssel:

palferi@lizi:~/proba$ ./c1.sc
1 a négyzeten = 1
4 a négyzeten = 16
7 a négyzeten = 49
10 a négyzeten = 100
...

Az alábbi program a proba könyvtár fájljainak neveit és tartalmát listázza ki. Minden fájl 3 másodpercig látható és köztük 1 másodpercig sötét a terminál. Ezek után kiírja a proba könyvtár állományinak számát.

#!/bin/bash
N=0
for i in `ls ~/proba`
do
clear
sleep 1
echo "A fájl neve: $i"
cat ~/proba/"$i"
sleep 3
N=`expr $N '+' 1`
done
clear
echo "A ~/proba könytárban $N fájl van"

A while ciklus

A while ciklusnál az ismétlést egy feltételhez kötjük. Amennyiben a feltétel igaz, a ciklusmag végrehajtódik. A ciklusfeltétel a ciklusmag végrehajtása előtt értékelődik ki, ezért elképzelhető, hogy a ciklusmag egyszer sem hajtódik végre.
Az alábbi szkript kiszámítja a paraméterében megadott egész szám faktoriálját.

#!/bin/bash
I=1
F=1
while test $1 -ge $I
do
F=`expr $F '*' $I`
I=`expr $I '+' 1`
done
echo "$1! = $F"

Vizsgáljuk meg a program működését. Az alábbi táblázat a változók értékeit mutatja a ciklusmag három ismétlődésekor és a ciklus végét, ha a paraméter 3:

1. ellenőrzés 2. ellenőrzés 3. ellenőrzés 4. ellenőrzés
a feltétel igaz: 3>=1a feltétel igaz: 3>=2a feltétel igaz: 3>=3a feltétel HAMIS: 3>=4
F=1*1=1 F=1*2=2 F=2*3=6
I=1+1=2 I=2+1=3 I=3+1=4
F=6

Az alábbi, c4.sc néven létrehozott szkript a paraméterbe megadott egész szám osztóit írja ki. Meghatározza az osztók számát, és ha ez a szám kettő, a prímszám szöveg jelenik meg.

#!/bin/bash
I=1 ; F=1 ; OT=1
while test $1 -gt $I
do
F=`expr $1 '%' $I`
    if test $F -eq 0
    then 
    echo "          $I"
    OT=`expr $OT '+' 1`
    fi
I=`expr $I '+' 1`
done
echo "          $1"
if test $OT -eq 2
then
echo "$1 - prímszám!"
else
echo "$1 -- $OT osztója van"
fi

Indítsuk a szkriptet különböző paraméterekkel és ellenőrizzük működését:

palferi@lizi:~/proba$ ./c4.sc 719
          1
          719
719 - prímszám!
palferi@lizi:~/proba$ ./c4.sc 81
          1
          3
          9
          27
          81
81 -- 5 osztója van

A until ciklus

A until ciklus felépítésben hasonlít a while-hoz, azonban ebben az esetben a do és done közötti utasítások addig hajtódnak végre, míg a feltétel igazzá nem válik.

Tömbök használata

Shell szkriptekben használhatunk egydimenziós tömböket. A tömbök elemeinek indexe egész szám, a sorszámozás nullától indul. A B tömb hármas indexű eleme: B[3]
A tömb hármas indexű elemének értéke pedig: ${B[3]} A tömb összes elemére hivatkozhatunk a * karakterrel: ${B[*]}
A következő feladat a tömbök használatát és az until ciklust mutatja be.

Feladat 1. Minimumkeresés

Írjunk szkriptet c5.sc néven ami beolvas tömbbe n egész számot. Az n értékét az első paraméterben adjuk meg. Az until ciklus használatával határozzuk meg a tömb legkisebb elemét.

#!/bin/bash
for i in `seq 1 $1`
do
echo -n "$i. szam: ?"
read TOMB[$i]
done
echo "A tömb $1 elemből áll: ${TOMB[*]}"
MIN=${TOMB[1]}
H=2
until test $H -gt $1
do
    if test ${TOMB[H]} -lt $MIN
    then
    MIN=${TOMB[H]}
    fi
H=`expr $H '+' 1`
done
echo "A tömb legkisebb eleme: $MIN"

A programban a for ciklus változója az i, egytől az első paraméterben megadott számig veszi fel az értékeket. A ciklus magja megjeleníti a sorszámot és a read paranccsal beolvassa a tömb megfelelő elemeit. Ezután kiírja a tömb elemeinek számát és a minden elemét.
A MIN változó fogja a tömb legkisebb elemét tartalmazni, de először az első elem értékét kapja. A H változó kezdeti értéke 2, hiszen a tömb második elemétől kell mindegyiket összehasonlítani a MIN változó értékével.
Ezt az until ciklus végzi. A ciklus magjában az adott elemet összehasonlítjuk a MIN értékével, és ha kisebb annál, akkor az adott elem lesz a MIN. A H értékét is növeljük eggyel a ciklusmagban, amikor olyan értéket kap, hogy a H nagyobb lesz mint a paraméterben megadott szám, a ciklus véget ér. A ciklus végeztével a MIN változó tartalmazza a tömb legkisebb elemét:

palferi@lizi:~/proba$ ./c5.sc 4
1. szam: ?54
2. szam: ?3
3. szam: ?9
4. szam: ?7
A tömb 4 elemből áll: 54 3 9 7
A tömb legkisebb eleme: 3

Feladat 2. Rendezés

Módosítsuk az előző szkriptet hogy a tömb elemeit rendezze buborék algoritmussal. Az algoritmusról részletesen itt olvashatunk: Wikipédia - Buborékrendezés
Az algoritmus pseudokódja a következő:

FOR J=1 TO N-1 STEP 1
 FOR I=1 TO N-J STEP 1
 IF A[I]>A[I+1] THEN SWAP A[I],A[I+1]
 NEXT I
NEXT J

A csere (SWAP) parancsot megvalósíthatjuk az alábbi sorokkal:

 TEMP=A[I]
 A[I]=A[I+1]
 A[I+1]=TEMP

Ezek alapján a szkript:

#!/bin/bash
for i in `seq 1 $1`
do
echo -n "$i. szam: "
read TOMB[$i]
done
echo "A tömb $1 elemből áll: ${TOMB[*]}"
# rendez
JJ=`expr $1 '-' 1`
for J in `seq 1 $JJ`
do
KK=`expr $1 '-' $J`
  for K in `seq 1 $KK`
  do
  KN=`expr $K '+' 1`
    if test "${TOMB[K]}" -gt "${TOMB[KN]}"
    then
    TEMP=${TOMB[K]}
    TOMB[K]=${TOMB[KN]}
    TOMB[KN]=$TEMP
    fi
  done
done
echo "A rendezett tömb: ${TOMB[*]}"

Próbáljuk ki a működését:

palferi@lizi:~/proba$ ./c6.sc 7
1. szam: 23
2. szam: 7
3. szam: 3
4. szam: 9
5. szam: -9
6. szam: 0
7. szam: 2
A tömb 7 elemből áll: 23 7 3 9 -9 0 2
A rendezett tömb: -9 0 2 3 7 9 23

< Vissza

st-linux_alapok/fejezetek/ciklusok.txt · Utolsó módosítás: 2016/05/01 01:03 szerkesztette: pferi