函数与数组

一、函数

1、函数的概念

定义:将命令序列按照格式写在一起。

作用:方便重复使用。

函数库,集中在一起,随时可以传参使用,大的工程分割成若干个小的功能模块,提供代码的可读性

函数格式:

第一种

function 定义的方法名{

命令序列

}

第二种

定义的方法名(){ 命令序列 }定义名(调用传参)

2、返回码

function abc {

num=$(($a*2))
return $num
}
a=10
abc
echo $?
#这里的$?不在具有判断执行结果,只是一个函数内部的返回值

return只能写在函数内部

目的:从函数的内部获取一个返回值,用来判断是否继续执行下一个脚本

在使用return传返回码的时候,默认0是成功,非0都是失败,返回码的值0-255之间,超过了会除256取余数,可以自定义

function abc {
read -p "数"  a
if [[ $a -eq $a ]] &> /dev/null
then
num=$(($a*2))
return 0
else
echo "输入错误"
return 1
fi
}
abc

 if [[ $? -eq 0 ]]
then
echo  ok
else
echo no
fi

3、 函数的传参方式已经函数变量的作用范围

1、传参方式

定义值
abc () {
num=$(($a+$b))
echo $num
}
read -p "第一个" a
read -p "第二个" b

abc
~ 
第二种方式
abc () {
num=$(($1+$2))
echo $num
}
abc $1 $2

2、函数变量的作用范围

abc () {
a=4
b=4
}
a=2
b=9
abc
ehco $a
echo $b
在函数内部定义了全局变量,
外部的赋值是不能改变内部函数的全局变量的

输出结果
a=4
b=4



abc () {
local a=4
local b=4
c=10
}
a=2
b=9
c=1
abc
echo $a
echo $b
echo $c
加了local之后就是函数内部的变量,而不是全局变量,外部的赋值会替换内部的变量值
输出
a=2
b=9
c=10

函数递归:函数调用自己本身的函数

实例:用函数递归的方式实现阶乘

abc () {
if [[ $1 -eq 1 ]]
then
 echo 1
else
 local temp=$(($1-1))
 local result=$(abc $temp)
 echo "$(($1*$result))"
fi
}
read -p "请输入你要计算的数字:" num
result1=`abc $num`  #``将运算出来的结果作为一个字符串进行输出
echo $result1

实例:用函数递归的方式实现递归目录到没有文件为止

递归目录,直到目录里面没有文件为止
jiecheng () {
for file in `ls $1`
do
#-d 测试目录
if [[ -d  "$1/$file"  ]]
then
  echo $file
  jiecheng "$1/$file"
else
 echo "不是一个目录$file"

fi
done
}
jiecheng $1

4、函数库

函数库中只包含定义的函数,由另外一个脚本传入参数来调用我们定义的函数

实例:小数+整数都可以运算 小数点后两位

函数库文件名hans3.sh

jiafa () {
result=$(echo "$1 + $2" | bc)
#结果保留两位小数
printf "%.2f\n" "$result" 
}
jianfa () {
result=$(echo "$1-$2" | bc)
#结果保留两位小数
printf "%.2f\n" "$result" 
}
chengfa () {
result=$(echo "$1*$2" | bc)
#结果保留两位小数
printf "%.2f\n" "$result" 
}
chufa () {
if [[ $2 -eq 0 ]]
then
 echo "除数不能为0"
else
result=$(echo " $1/$2" | bc)
#结果保留两位小数
printf "%.2f\n" "$result" 
}

调用函数 文件名diaoyong3.sh

. /opt/hanshu3.sh
read -p "输入第一个数:" num1
read -p "输入第一个数:" num2
sum=`jiafa $num1 $num2`
sub=`jianfa $num1 $num2`
mult=`chengfa $num1 $num2`
div=`chufa $num1 $num2`
echo $sum
echo $sub
echo $mult
echo $div

运行调用函数前需要给函数库赋可执行权限

二、数组

1、数组的概念

数组:在集合当中指定多个元素,元素的类型:整数,字符串,可以是浮点

作用:一次性定义多个元素,可以位变量赋值提供便利

数组的定义方法:

数组名=(元素值) 数组名不能重复

数组名=(a b c d)

打印数组值echo ${数组名[* ]}或者echo ${数组名[@]}

#两种定义的方法
[root@localhost opt]# test1=(a b c d)
[root@localhost opt]# echo ${test1[*]}
a b c d
#[0]中的0表示下标,从0开始
[root@localhost opt]# test[0]=1
[root@localhost opt]# test[1]=2
[root@localhost opt]# test[2]=3
[root@localhost opt]# echo ${test[*]}
1 2 3

数组的长度指的是数组内包含了几个元素

echo ${#test[*]} 或者echo ${#test[@]}

#test内包含了3个文件
[root@localhost opt]# echo ${#test[*]}
3

查看数组第几个内容

[root@localhost opt]# test3=(11 22 33)
[root@localhost opt]# echo ${test3[0]}
11
[root@localhost opt]# echo ${test3[1]}
22
[root@localhost opt]# echo ${test3[2]}
33

对数组进行遍历

#对数组进行遍历
test4=(aa bb cc dd)
for i in ${test4[*]}
do
echo $i
done

结果

[root@localhost opt]# sh shuzu1.sh 
aa
bb
cc
dd

对数组进行切片

[root@localhost opt]# test5=(1 2 3 4 5)
#0表示起始位置,2表示步长,起始位置0开始,包括0移动2个
[root@localhost opt]# echo ${test5[*]:0:2}
1 2
[root@localhost opt]# echo ${test5[*]:1:3}
2 3 4

[root@localhost opt]# echo ${test1[*]}
a b c d
[root@localhost opt]# echo ${test1[*]:1:1}
b
[root@localhost opt]# echo ${test1[*]:1:2}
b c

2、数组替换

临时替换,不会真正改变数组值

[root@localhost opt]# echo ${test5[*]/1/a}
a 2 3 4 5
[root@localhost opt]# echo ${test5[*]}
1 2 3 4 5

永久修改,通过修改元素下标的值可以实现

[root@localhost opt]# test5[0]=b
[root@localhost opt]# echo ${test5[*]}
b 2 3 4 5
[root@localhost opt]# test5[4]=e
[root@localhost opt]# echo ${test5[*]}
b 2 3 4 e

3、删除数组

删除整个数组

[root@localhost opt]# unset test1
[root@localhost opt]# echo ${test1[*]}

[root@localhost opt]# 

删除数组中的元素,元素下标的值不会发生变化

[root@localhost opt]# unset test5[0]
[root@localhost opt]# echo ${test5[*]}
2 3 4 e
[root@localhost opt]# echo ${test5[0]}

[root@localhost opt]# echo ${test5[1]}
2

4、数组中进行追加

#根据元素下标,指定追加
[root@localhost opt]# echo ${test5[*]}
2 3 4 e
[root@localhost opt]# test5[0]=a
[root@localhost opt]# echo ${test5[*]}
a 2 3 4 e
[root@localhost opt]# test5[6]=9
[root@localhost opt]# echo ${test5[*]}
a 2 3 4 e 9

#自动追加

[root@localhost opt]# test5+=(qq oo)
[root@localhost opt]# echo ${test5[*]}
a 2 3 4 e 9 qq oo

#追加只能在最后开始追加,中间缺失的部分不会补齐
[root@localhost opt]# echo ${test5[*]}
a 2 3 4 e 9 qq oo
[root@localhost opt]# unset test5[4]
[root@localhost opt]# echo ${test5[*]}
a 2 3 4 9 qq oo
[root@localhost opt]# test5+=(ddd)
[root@localhost opt]# echo ${test5[*]}
a 2 3 4 9 qq oo ddd
[root@localhost opt]# echo ${test5[4]}

实例:定义一个数组,元素都是整数,实现数字内整数的累加求和

sum=0
test1=(10 20 30 40 50)
for i in ${test1[*]}
do
sum=$(($sum+$i))
done
echo $sum

实例:定义一个数组,元素都是整数,分别求出偶数,奇数累加求和

sum1=0
sum2=0
test1=(10 15  40 61 31 42)
for i in ${test1[*]}
do
if [[ $((i%2)) -eq 0 ]]
then
sum1=$(($sum1+$i))
else
sum2=$(($sum2+$i))
fi
done
echo "偶数的和为:$sum1"
echo "奇数的和为:$sum2"
运行结果
[root@localhost opt]# sh shuzu2.sh
偶数的和为:92
奇数的和为:107

实例:定义一个数组,并取出一个最小值,最大值

test1=(3 5 7 4 1)
max=${test1[0]}
min=${test1[0]}
for i in ${test1[*]}
do
if [[ $i -gt $max ]]
then
 max=$i
fi
if [[ $i -lt $min ]]
then
 min=$i
fi
done
echo "max=$max"
echo "min=$min"

结果

[root@localhost opt]# sh shuzu2.sh
max=7
min=1

5、冒泡排序

冒泡排序类似于气泡上涌的工作,会将数组当中的元素按照从小到大,或者从大到小的顺序进行一个重新排列

从小到大排

思路:对比两个相邻的元素,以从下到大为例,满足交换条件的元素,小的往左移,大的往右移动

数组的位置发生变化(下标对应的元素的值发生变化)

双层循环,外部循环控制排序的轮次,内部循环用来对比两个元素的大小,决定是否互换位置

对比和交换的次数随着排序轮次而减少

实例:使用冒泡排序将test1的内容进行从小到大进行排序

test1=(20 10 60 40 50 30)
len=${#test1[*]}
#定义排序的轮次
for ((i=1;i<$len;i++))
do
 for ((k=0;k<$len-i;k++))
 do
#定义第一个数组的值
 first=${test1[$k]}
 j=$(($k+1))
#定义第二个下标位置
 second=${test1[$j]}
 if [ $first -gt $second ]
 then
#交换位置
 temp=$first
 test1[$k]=$second
 test1[$j]=$temp
fi
 done
echo "排序后的数组值为:${test1[*]}"
done  

实例:使用冒泡排序将df的已用进行从大到小进行排序

# 取出已用并将%去掉
test1=($(df -h | awk 'NR>1 {print $5}' | tr -d '%'))
len=${#test1[*]}
#定义排序的轮次
for ((i=1;i<$len;i++))
do
 for ((k=0;k<$len-i;k++))
 do
#定义第一个下标的值
 first=${test1[$k]}
 j=$(($k+1))
#定义第二个下标位置
 second=${test1[$j]}
 if [ $first -le $second ]
 then
#交换位置
 temp=$first
 test1[$k]=$second
 test1[$j]=$temp
fi
 done
done
echo "排序后的数组值为:${test1[*]}"
相关推荐
bingbingyihao30 分钟前
Linux安装ftp、Java的FTP上传下载文件工具类
java·linux·centos
墨鸦_Cormorant35 分钟前
VPN 的入门介绍
服务器·网络·安全·vpn
krb___43 分钟前
Gitlab代码管理工具安装配置
linux·服务器·gitlab
XF鸭1 小时前
HTML-CSS 入门介绍
服务器·前端·javascript
噫吁嚱!!!1 小时前
Linux安装elasticsearch单机版
linux·运维·ubuntu
lshzdq1 小时前
【CMake】基本概念和快速入门
linux·运维·服务器
爱技术的小伙子2 小时前
Linux 磁盘管理与分区:使用fdisk、parted、df、du等命令管理磁盘和分区
linux·运维·服务器
Java小白白同学2 小时前
Linux:CentOS 系统磁盘扩容操作
linux·服务器·centos
semicolon_hello2 小时前
使用C++编写TCP服务端程序
服务器·网络·c++·tcp/ip
wanhengwangluo2 小时前
徐州服务器租用:论带宽的作用有哪些
运维·网络安全·数据安全