函数与数组

目录

一、函数

(一) 函数的意义

(二)函数的基本格式

(三)查看函数

(四)删除函数

(五)锁定变量

(六)函数返回值

1.return的具体用法

(七)函数传参

(八)函数递归

二、数组

(一)数组基本

(二)数组遍例

(三)数组切片

(四)冒泡排序

1.取数组中最大值

2.取数组中最小值

3.同时求最大值和最小值

4.冒泡排序


一、函数

(一) 函数的意义

        所谓函数是将一组功能相对独立的代码集中起来,从而形成一个代码块,这个代码可以相对独立的完成某个功能,同时函数名与函数体形成映射,也就是说用户定义了函数后可以使用函数名来完成调用函数体,使开发更加的方便,代码更加简洁。语句块定义成函数约等于别名

(二)函数的基本格式

1.
function 函数名{ 
​	命令序列
}

2.
函数名(){
  命令序列
}

3.
function func_name (){
 ...函数体...
} 

调用函数

function_name param1 param2 …      

 在上面的语法中,function_name 表示函数名称,其后面跟的 param1 、 param2… 表示函数 的参数

调用函数 : 直接执行函数名即可      

 函数名

带参数的函数的执行方法:      

函数名 参数

注意事项:

1.直接写函数中调用函数,直接写函数名

2.同名函数,后一个生效

3.调用函数一定要先定义

4.每个函数是独立

函数与数组_第1张图片

写一个基本的函数文件

函数与数组_第2张图片

(三)查看函数

使用declare命令

-F:查看函数名

函数与数组_第3张图片

-f:函数具体信息

函数与数组_第4张图片

也可以指定查看一个函数的具体信息

(四)删除函数

unset  函数名

函数与数组_第5张图片

(五)锁定变量

函数变量的作用范围:

函数在shell脚本中仅在当前的shell环境中有效

shell脚本中函数的变量默认全局有效

将变量限定在函数内部使用local命令

举个例子

函数与数组_第6张图片

(六)函数返回值

return表示退出函数并返回一个退出值,脚本中可以用$?变量表示该值

使用原则:

1.函数一结束就去返回值,应为$?变量只返回执行的最后一条命令的退出返回码

2.退出码必须是0-255,超出的值将为除以256取余

return 0 无错误返回

return 1-255 有错误返回

函数与数组_第7张图片

函数与数组_第8张图片

可以看到,脚本正常执行后,返回退出状态码为0,但是,脚本中有错误的命令,执行脚本后,状态码依然为0

所以,我们可以自定义一个返回值

函数与数组_第9张图片

函数与数组_第10张图片1.return的具体用法

第一种是无返回值函数:即使函数不返回任何值(即 void 函数),也可以使用return语句来提早结束函数执行,不过在这种情况下通常可以省略return语句,因为函数会自动在执行完最后一行代码后返回

第二种是多路径返回

根据不同的逻辑分支,函数可能通过多个位置上的 return 语句返回不同的结果。

函数与数组_第11张图片

简单来说,就是在不同的逻辑分支上给出不同的返回值,便于处理脚本中的错误

在上图的脚本中,可以这样理解,如果条件符合判断条件,说明该条命令有误,直接退出脚本,并返回相对应的退出状态码

函数与数组_第12张图片

我们可以使用该方法,在函数中检测到一些不能执行的命令后直接退出,并返回指定的状态码,有助于去排查错误

也可以设置变量值为返回值,将该段脚本执行后所得到的结果,设为返回值,通过返回值,来判断该段脚本对自己的作用,选取段落进行详细查看,不需要将脚本从头到尾执行一遍

函数与数组_第13张图片

函数与数组_第14张图片

(七)函数传参

在Linux shell脚本中,函数传参是指在调用自定义函数时向该函数传递参数的过程。这些参数可以

在函数内部作为变量使用,以便函数能够根据传入的数据执行不同的任务或操作

函数与数组_第15张图片

#在这个例子中:

#函数 add_numbers 接受两个参数 $1 和 $2。
#参数通过位置来引用,即 $1 是第一个参数,$2 是第二个参数。
#在函数体内部,通过 $1 和 $2 访问传递进来的参数值,并进行加法运算。
#结果被存储在局部变量 result 中,并通过 echo 输出。
#当调用 add_numbers 3 5 时,函数接收到参数 3 和 5,计算它们的和并将结果返回给调用者。

函数与数组_第16张图片

(八)函数递归

在Shell脚本中实现函数递归是一个有趣且强大的编程技术。下面是一个使用递归来计算阶乘的简单示例

在开始讲解之前,先带大家了解一些什么是阶乘

 阶乘是指一个正整数 n 和小于等于 n 的所有正整数的乘积。通常用符号 "!" 表示,表示为 n!。

例如,4! = 4 × 3 × 2 × 1 = 24。

知道什么是阶乘以后,来带大家了解一下如何用递归来计算阶乘结果

函数与数组_第17张图片

# 定义一个递归函数来计算阶乘
factorial() {
    if [ "$1" -eq 0 ]; then
 # 阶乘的基本情况:0的阶乘是1
        echo 1
    else
local temp=$[$1 - 1] # 递归调用自身,将n-1作为新的参数
local result=$(factoridl $temp) #将每次的新参数设置为新的第一个参数,即为$1
echo $[ $1 * $result ]  #计算当前数与递归结果的乘积
#如果需要求5的阶乘,那么第一次调用函数时为$1为temp=$1-1,结果为4,result为第一次递归调用函数时
#后面的新的参数。即temp=$1-1,数值为3。那么第一步运算就是4($1)x3($result)=12,以此类推,然后
#将递归得到的结果与原始数字5相乘以得到最终的阶乘值
    fi
}
# 从命令行读取用户输入的数字
read -p "请输入一个非负整数: " n
# 检查输入是否为非负整数
if [[ ! "$n" =~ ^[0-9]+$ ]]; then
    echo "错误:输入必须是非负整数!"
else
    # 调用递归函数并打印结果
    result=$(factorial $n)
    echo "该数字的阶乘是: $result"
fi

那么,我们来实验一下吧

函数与数组_第18张图片

二、数组

在Shell脚本中,数组是一种可以存储多个值的数据结构。与许多其他编程语言中的数组类似,Shell脚本中的数组允许你为一组相关的数据分配一个名称,并通过索引来访问这些数据

(一)数组基本

数组的定义格式为:数组名=(value0 value1 value2 value3 ...... )

1.数组名=(value0 value1 value2 value3 ......)

2.数组名=([0]=value [1]=value1 [2]=value2 ....)

3.列表名="value0 value1 value2 value3 ...... "

   数组名=($列表名)

4.数组名[0]="value1"

   数组名[1]="value2"

   数组名[2]="value3"

调用数组的方法为${数组名[位数]}

函数与数组_第19张图片

最简单的数组就是a=(10  20  30  40  50),而后再通过命令来调用特定变量

函数与数组_第20张图片

输入echo  ${!a[*]},查看所有下标

输入declare  -a 可以看到所有的数组信息

函数与数组_第21张图片

加#号显示数组长度,也就是显示该数组有多少个值

也可以进行单个值的修改

函数与数组_第22张图片

(二)数组遍例

数组遍历是指按照某种顺序访问数组中的每一个元素

在Bash shell脚本中,遍历数组可以使用for循环配合特殊的变量来完成

函数与数组_第23张图片

函数与数组_第24张图片

或者获取下标(索引)和值一起来进行遍例

函数与数组_第25张图片

函数与数组_第26张图片

第一个for循环通过${myArray[@]}来访问数组中的每个元素,并将其赋值给item,然后输出。

第二个for循环利用特殊变量${!myArray[@]}来获取数组下标(索引),并通过${myArray[$index]}访问对应索引的数组元素,同时输出索引和对应的值。

请注意,在Shell脚本中,数组索引是从0开始的。

(三)数组切片

数组切片在编程中是一种提取或操作数组部分元素的功能。它允许你从一个数组或列表中选择一个子集,而不仅仅是单个元素。通过数组切片,你可以根据需要获取连续的一段数据,并且可以灵活地指定起始位置、结束位置以及步长(可选)

例如在一个数组中,只想去第三个到第五个数的值

函数与数组_第27张图片

数组切片的作用在于:

提取数组的部分内容,无需复制整个数组。

灵活处理和分析数据集合的一部分。

在算法设计和数据处理过程中提供了一种简洁高效的表达方式

(四)冒泡排序

在Shell脚本中实现冒泡排序,需要通过循环和条件判断来逐步比较并交换数组中的元素。冒泡排序的基本原理是重复遍历要排序的数列,每次遍历时都将相邻的两个元素进行比较,如果它们的顺序错误(例如当前元素大于下一个元素),则交换这两个元素的位置。每一轮遍历后,最大的元素就像气泡一样逐渐“浮”到数列的顶端,直到最后一个数值定位在第一个索引位置,即排序结束。

首先,我们来做个实验

1.取数组中最大值

函数与数组_第28张图片

read -p  "请输入一组数字"  A
a=( $A )    #将输入的数字按默认排序,设置为数组a
max=${a[0]} #假设第一个数为最大数,设为max
l=${#a[@]}  
#打印出数组长度,即数组值的个数,并设置为变量l。比如,该数组内有5个
#数字,那么该数组的下标数为0,1,2,3,4。有五个下标,数组长度就为5

for ((i=0;i<$l;i++))
#i=0:因为下标第一个数字为0,所以i的初始值为0
#i<$l:因为下标不会大于或等于数组的长度,当条件成立时才会进入循环
#i++:每次循环后i的值+1,循环代表a数组的下标
do
if  [[ $max -lt ${a[$i+1]} ]]  #{a[$i+1]}:下标数+1的数值,也就是下一个数
#判断条件:当假设的最大数,小于下一个数,条件成立
then
max=${a[$i+1]}
#当条件成立时max的值会定义为下一个数的数值
fi
done
#以此类推,直到最后,max的值即为数组中最大的值
echo "最大数为:$max"

2.取数组中最小值

理论与取最大值一致,在遍历过程中需要小心避免越界访问,即在比较最后一个元素时无需加上1。需要将$l-1,并将判断条件 -lt(小于)改为         -gt(大于)即可

函数与数组_第29张图片

3.同时求最大值和最小值

函数与数组_第30张图片

#!/bin/bash

for i in {0..9}   #循环10次,因为下标从0开始,循环值也从0开始
do
a[$i]=$RANDOM  #每循环一次,a数组的长度+1,数值为$RANDOM的随机值
#比如第一次执行脚本时a[0]=$RANDOM的随机值,循环下一次为a[1]=$RANDOM的随机值

[ $i -eq 0 ] && min=${a[0]} && max=${a[0]}
#当下标为0时,假设第一个数值为最小值,也设这个数为最大值
[ ${a[$i]}  -gt  $max ]  && max=${a[$i]}
#当第下一次循环的数大于这个第一个数,那么max变量值就为这个数
[ ${a[$i]}  -lt  $min ]  && min=${a[$i]}
#当第下一次循环的数小于这个第一个数,那么min变量值就为这个数
done
#依次类推,一个数每次经过大小各轮的比较,得到最终的结果
echo  ${a[@]}
echo  "最大数为:$max"
echo  "最小数为:$min"

4.冒泡排序

在Shell脚本中,冒泡排序的主要作用是用来对一组数值(通常是数组中的元素)进行排序。冒泡排序是一种简单的排序算法,其基本工作原理是通过重复遍历待排序的数列,一次比较两个相邻元素,并在需要的情况下交换它们的位置,直到整个序列不再需要任何交换为止。这样做的结果就是,就像水中的气泡上升到水面一样,最大的元素“浮”到了数列的一端(对于升序排序),最小的元素则“沉”到了另一端。

在Shell脚本的具体应用中,如果你有一个数值型数组变量,你可以使用冒泡排序方法对其进行排序,例如按照从小到大的顺序排列数组中的元素。这种排序方法尤其适用于教育和学习环境,因为它逻辑直观且易于实现,尽管在实际生产环境中,由于效率相对较低,通常不作为首选排序算法。但对于小型数据集或性能要求不高的场景,冒泡排序可以作为一种简单有效的解决方案。

函数与数组_第31张图片

# 定义一个数组并初始化元素
arr=(5 3 8 4 2)

# 获取数组长度
len=${#arr[@]}

# 冒泡排序函数
bubble_sort() {
    for ((i=0; i<$len-1; i++)); do
        for ((j=0; j<$len-i-1; j++)); do
            if [ ${arr[j]} -gt ${arr[j+1]} ]; then
                # 如果前一个元素大于后一个元素,则交换它们的位置
                temp=${arr[j]} #先将一个数定义一个其它变量
                arr[j]=${arr[j+1]}
                arr[j+1]=$temp
              #而后将两个数值进行调换  
          fi
        done
    done
}

# 调用冒泡排序函数
bubble_sort

# 输出排序后的数组
echo "Sorted array: ${arr[*]}"

排序后arr数组值为

你可能感兴趣的:(linux)