Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม BASH

เจาะลึกความซับซ้อนของฟังก์ชันด้วย Shell Scripting – ตอนที่ VII

บทความก่อนหน้าของฉันเกี่ยวกับ "การทำความเข้าใจและการเขียนฟังก์ชันในเชลล์สคริปต์" อาจให้แนวคิดพื้นฐานเกี่ยวกับวิธีเขียนฟังก์ชันภายใต้เชลล์สคริปต์ ตอนนี้ได้เวลาเจาะลึกถึงคุณสมบัติการทำงาน เช่น การใช้ตัวแปรในเครื่องและการเรียกซ้ำ

เจาะลึกความซับซ้อนของฟังก์ชันด้วย Shell Scripting – ตอนที่ VII

ตัวแปรท้องถิ่น

อะไรทำให้ตัวแปรท้องถิ่น? ขึ้นอยู่กับบล็อกเฉพาะที่ประกาศตัวแปร ตัวแปรที่ประกาศเป็น local จะสามารถเข้าถึงได้จากบล็อกของรหัสที่ปรากฏ เช่น ขอบเขตอยู่ในเครื่อง เพื่ออธิบายสิ่งนี้ เรามาดูตัวอย่างด้านล่างกัน

#!/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

ในการรันสคริปต์ข้างต้น ผลลัพธ์จะเป็น

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

เนื่องจากเป็นฟังก์ชัน func ยังไม่ได้เรียกในขณะที่ 2 คนแรก คำสั่ง echo ถูกดำเนินการ หลังจากเรียกใช้ฟังก์ชัน func 2 คำสั่ง echo เดียวกัน ให้ผลลัพธ์ที่แตกต่าง ตอนนี้ตัวแปร j ซึ่งประกาศไว้ใน func และไม่สามารถเข้าถึงได้ในภายหลัง

ดังนั้นค่าสำหรับ j กลายเป็น 20 . สิ่งที่เกี่ยวกับตัวแปรท้องถิ่น i ? เนื่องจากขอบเขตของมันอยู่ภายในฟังก์ชัน func , ค่า 10 ไม่สามารถเข้าถึงได้จากภายนอก โปรดทราบว่าตัวแปร j ปกติจะประกาศอยู่ภายใน func เป็นสากลโดยค่าเริ่มต้น

ตอนนี้คุณคุ้นเคยกับตัวแปรในเครื่องแล้วและวิธีใช้งานภายในบล็อกฟังก์ชัน ให้เราไปยังส่วนที่น่าสนใจที่สุดภายใต้ฟังก์ชั่นการเรียกซ้ำ

การเรียกซ้ำคืออะไร

โดยทั่วไปฟังก์ชันที่เรียกตัวเองว่ากระบวนการเรียกซ้ำ หรือสามารถกำหนดเป็นการแสดงอัลกอริทึมโดยใช้เวอร์ชันที่ง่ายกว่าของอัลกอริทึมเดียวกันนั้น พิจารณาตัวอย่างการหาแฟกทอเรียลของจำนวน เรารู้ว่า น! =1 x 2 x 3 x … x (n-1) x n . ดังนั้นเราสามารถเขียนความสัมพันธ์การเกิดซ้ำเป็น:

n! = (n-1)! x n

ดังนั้นจึงง่ายสำหรับเราที่จะเรียกใช้ฟังก์ชันเดียวกันซ้ำๆ และใช้ค่าที่ส่งคืนจากการเรียกแต่ละครั้งเพื่อคูณกับผลลัพธ์ก่อนหน้า นั่นคือ

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

การเรียกซ้ำโดยใช้ตัวแปรในเครื่อง

ที่นี่เราพยายามเขียนสคริปต์เพื่อค้นหาแฟกทอเรียลของตัวเลขโดยใช้ตัวแปรโลคัลและการเรียกซ้ำ

#!/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

จำนวน เป็นตัวแปรท้องถิ่นที่ใช้เก็บแต่ละ n-1 มูลค่าในการโทรแต่ละครั้ง ที่นี่เงื่อนไขพื้นฐานจะตรวจสอบว่าตัวเลขมีค่าเท่ากับศูนย์หรือไม่ (เนื่องจาก 0! =1 และแฟกทอเรียลไม่ได้กำหนดไว้สำหรับตัวเลขติดลบ) เมื่อมาถึงเงื่อนไขพื้นฐานนี้จะคืนค่า 1 ถึงผู้โทร ตอนนี้ num =1 และ ret =1 x 1 .

ในขณะนี้มันกลับมา 1 ถึงผู้โทร ตอนนี้ num =2 และ ret =2 x 1 และอื่นๆ สุดท้ายเมื่อ num =5 ค่าที่ส่งคืนจะเป็น 24 และผลลัพธ์สุดท้ายคือ ret =5 x 24 . ผลสุดท้าย 120 จะถูกส่งต่อไปยังข้อความแจ้งผู้โทรเริ่มต้นและแสดงขึ้น

มีปัญหาหนึ่งข้อในสคริปต์ข้างต้น ตามที่ได้อธิบายไปในบทความที่แล้ว ฟังก์ชันไม่สามารถคืนค่าจำนวนเต็มขนาดใหญ่ได้ ผู้ใช้จึงต้องหาวิธีแก้ไขปัญหาข้างต้น

ถาม เราสามารถทำการเรียกซ้ำโดยไม่ใช้ตัวแปรในเครื่องได้หรือไม่? คำตอบคือใช่ .

การเรียกซ้ำโดยไม่มีตัวแปรในเครื่อง

ดูตัวอย่างต่อไปนี้เพื่อแสดง อนุกรมฟีโบนักชี โดยใช้การเรียกซ้ำ ความสัมพันธ์การเกิดซ้ำพื้นฐานคือ:

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

ไม่มีการใช้ตัวแปรโลคัลในสคริปต์ด้านบน ฉันหวังว่าคุณจะเข้าใจโฟลว์ของสคริปต์ในระหว่างการดำเนินการ

ที่นี่ค่า 15 หมายถึงจำนวนพจน์ใน อนุกรมฟีโบนักชี ที่จะแสดง คุณสังเกตเห็นอะไรพิเศษเกี่ยวกับการดำเนินการของสคริปต์ข้างต้นหรือไม่ มันต้องใช้เวลาซักพักไม่ใช่เหรอ? การเรียกซ้ำในสคริปต์ช้ากว่าการเรียกซ้ำในภาษาโปรแกรมเช่น C .

ในบทความนี้ ฉันวางแผนที่จะสรุปส่วนฟังก์ชันในเชลล์สคริปต์ อัปเดตอยู่เสมอด้วย Tecmint มีบทความเกี่ยวกับ อาร์เรย์ . ที่กำลังจะมีขึ้นเร็วๆ นี้ และอีกมากมาย…