Lebih Dalam Tentang Kompleksitas Fungsi dengan Shell Scripting – Bagian VII


Artikel saya sebelumnya tentang “Memahami dan Menulis Fungsi di Skrip Shell” mungkin telah memberi Anda gambaran dasar tentang cara menulis fungsi di bawah skrip Shell. Sekarang saatnya mempelajari lebih dalam fitur fungsional seperti penggunaan variabel lokal dan rekursi.

Variabel Lokal

Apa yang membuat variabel menjadi lokal? Itu tergantung pada blok tertentu tempat variabel dideklarasikan. Variabel yang dideklarasikan sebagai local akan dapat diakses dari blok kode tempat variabel tersebut muncul, yaitu cakupannya bersifat lokal. Untuk menjelaskan hal ini mari kita lihat salah satu contoh di bawah ini.

#!/bin/bash 

func( ) { 
	local i=10 
	j=20 
	echo "i from func = $i" 
	echo "j from func = $j" 
} 

echo "i outside func = $i" 
echo "j outside func = $j" 

func 

echo "i outside func = $i" 
echo "j outside func = $j" 

exit 0

Saat menjalankan skrip di atas, hasilnya akan seperti ini.

i outside func = 
j outside func = 
i from func = 10 
j from func = 20 
i outside func = 
j outside func = 20

Hal ini karena fungsi func belum dipanggil ketika pernyataan echo 2 pertama dieksekusi. Setelah memanggil fungsi func 2 pernyataan echo yang sama menghasilkan hasil yang berbeda. Sekarang variabel j, yang dideklarasikan di dalam func dan bukan lokal, dapat diakses setelahnya.

Dengan demikian nilai j menjadi 20. Bagaimana dengan variabel lokal i? Karena cakupannya berada di dalam fungsi fungsi, nilai 10 tidak dapat diakses dari luar. Perhatikan bahwa variabel j yang biasanya dideklarasikan di dalam func bersifat global secara default.

Sekarang Anda sudah familiar dengan variabel lokal dan cara menggunakannya di dalam blok fungsi. Mari kita beralih ke bagian paling menarik di bawah fungsi, rekursi.

Apa itu Rekursi?

Suatu fungsi yang memanggil dirinya sendiri umumnya disebut sebagai prosedur rekursi. Atau dapat didefinisikan sebagai mengekspresikan suatu algoritma dengan menggunakan versi yang lebih sederhana dari algoritma yang sama. Perhatikan contoh mencari faktorial suatu bilangan. Kita tahu bahwa n!=1 x 2 x 3 x … x (n-1) x n. Dengan demikian kita dapat menulis relasi perulangan sebagai:

n! = (n-1)! x n

Jadi mudah bagi kita untuk memanggil fungsi yang sama secara rekursif dan menggunakan nilai kembalian dari setiap panggilan untuk mengalikannya dengan hasil sebelumnya, yaitu.

5! = 4! x 5
4! = 3! x 4
3! = 2! x 3
2! = 1! x 2
1! = 0! x 1

Rekursi menggunakan Variabel Lokal

Disini kami mencoba menulis skrip untuk mencari faktorial suatu bilangan menggunakan variabel lokal dan rekursi.

#!/bin/bash 

fact( ) { 
	local num=$1 
	if [ $num -eq 0 ]; then 
		ret=1 
	else 
		temp=$((num-1)) 
		fact $temp 
		ret=$((num*$?)) 
	fi 
	return $ret 
} 

fact 5 

echo "Factorial of 5 = $?" 

exit 0

num adalah variabel lokal yang digunakan untuk menyimpan setiap nilai n-1 pada setiap panggilan. Di sini kondisi dasar memeriksa apakah bilangan tersebut sama dengan nol atau tidak (karena 0!=1 dan faktorial tidak ditentukan untuk bilangan negatif). Saat mencapai kondisi dasar ini, ia mengembalikan nilai 1 ke pemanggilnya. Sekarang angka=1 dan ret=1 x 1.

Saat ini ia mengembalikan 1 ke pemanggilnya. Sekarang num=2 dan ret=2 x 1 dan seterusnya. Akhirnya ketika nilai kembalian num=5 adalah 24 dan hasil akhirnya adalah ret=5 x 24. Hasil akhir 120 diteruskan ke pernyataan pemanggil awal dan ditampilkan.

Ada satu masalah pada skrip di atas. Seperti yang saya jelaskan di artikel sebelumnya, fungsi tidak bisa mengembalikan bilangan bulat besar. Jadi terserah pengguna untuk menemukan solusi untuk masalah di atas.

T. Bisakah kita melakukan rekursi tanpa menggunakan variabel lokal? Jawabannya adalah Ya.

Rekursi tanpa Variabel Lokal

Lihat contoh berikut untuk menampilkan Deret Fibonacci menggunakan rekursi. Relasi perulangan dasar adalah:

fib(0) = 0 
fib(1) = 1 
else 
	fib(n) = fib(n-1) + fib(n-2)

Fibonacci series using recursion

#!/bin/bash 

fib( ) { 
	a=$1 
	if [ $a -lt 2 ]; then 
		echo $a 
	else 
		((--a)) 
		b=$(fib $a) 

		((--a)) 
		c=$(fib $a) 

		echo $((b+c)) 
	fi 
} 

for i in $(seq 0 15) 
do 
	out=$(fib $i) 
	echo $out 
done 

exit 0

Tidak ada variabel lokal yang digunakan dalam skrip di atas. Saya harap Anda dapat memahami alur skrip selama eksekusi.

Di sini nilai 15 mewakili jumlah suku dalam Deret Fibonacci yang akan ditampilkan. Apakah Anda memperhatikan sesuatu yang istimewa mengenai eksekusi skrip di atas. Butuh waktu cukup lama, bukan? Rekursi dalam skrip lebih lambat dibandingkan rekursi dalam bahasa pemrograman seperti C.

Dengan artikel ini, saya berencana untuk menyimpulkan bagian fungsi dalam skrip shell. Ikuti terus Tecmint untuk mendapatkan artikel mendatang tentang array dan banyak lagi…