1:数组
如果要存储班级里所有学生的数学成绩,应该怎样存储呢?可能有同学说,通过定义变量来存储。但是,问题是班级有80个学生,那么要定义80个变量吗?
像以上情况,最好是通过数组的方式来存储。
所谓的数组:是指一系列同一类型数据的集合。
(1.1) 数组定义
数组定义也是通过var 关键字,后面是数组的名字a,长度是10,类型是整型。表示:数组a能够存储10个整型数字。也就是说,数组a的长度是10。
我们可以通过len( )函数测试数组的长度,如下所示:
当定义完成数组a后,就在内存中开辟了10个连续的存储空间,每个数据都存储在相应的空间内,数组中包含的每个数据被称为数组元素(element),一个数组包含的元素个数被称为数组的长度。
注意:数组的长度只能是常量。以下定义是错误的:
var n int = 10
var a [n]int
(1.2)数组赋值
数组定义完成后,可以对数组进行赋值操作。
数组是通过下标来进行操作的,下标的范围是从0开始到数组长度减1的位置。
var a[10] int 表示的范围是a[0],a[1],a[2]…….,a[9]
完成对数组赋值的第一种方法:
如果现在给a[10]=29, 会出现什么情况呢?
但是这种赋值方式比较麻烦,所以可以使用第二种赋值方式,如下所示:
通过for循环完成数组的赋值与输出。注意:循环的条件,如果将循环条件修改成i<=10是否正确
在上一节中,我们说过可以通过len( )函数来获取 数组的长度,所以也可以对上面的程序,进行如下的修改:
对数组中的数据输出,也可以使用range.如下所示:
i变量存储的是数组的下标,data变量存储的是数组中的值。
如果只想输出数组中的元素值,不希望输出下标,可以使用匿名变量
上面的案例中,首先完成了数组的赋值,然后再输出数组中的值。但是,如果定义完成数组后,没有赋值,直接输出会出现什么样的问题呢?
a数组中的元素类型是整型,定义完成后,直接输出,结果全部是0.
当然数组中存储的元素类型也可以是其它类型,如下所示:
var a [10]float64//如果不赋值,直接输出,结果默认全部是0
vara[10]string//如果不赋值,直接输出,结果默认全部是空字符
var a [10]bool//如果不赋值,直接输出,结果默认全部是false.
(1.3):数组初始化
上一小节中,首先先定义数组,然后再完成数组的赋值。其实,在定义数组时,也可以完成赋值,这种情况叫做数组的初始化。
具体案例如下:
(1.4)数组练习
练习1:从一个整数数组中取出最大的整数,最小整数,总和,平均值。
代码如下:
func main() {
//从一个整数数组中取出最大的整数,最小整数,总和,平均值。
a := [6]int{12, 2, 32, 13, 42, 9}
var max, min, sum int
var pj float64
fmt.Println(a)
for i := 0; i < len(a); i++ {
if a[i] > max {
max = a[i]
}
if a[i] < min {
min = a[i]
}
sum += a[i]
pj = float64(sum) / float64(len(a))
}
fmt.Println("最大值是:", max)
fmt.Println("最小值是:", min)
fmt.Println("总和为:", sum)
fmt.Printf("平均值为:%.2f", pj)
}
# 结果
最大值是: 5
最小值是: 0
总和为: 15
平均值为:2.50
通过观察发现该程序输出的结果没有问题。
但是,现在将程序进行如下修改:将数组中的0元素删除,同时将数组的长度修改为5.
运行以上程序,结果如下:
思考:数组中没有0,为什么输出的结果中最小值为0呢?
现在,在将程序进行如下修改:将数组中的数据全部修改成负数。
运行该程序,结果输出:
思考:数组中没有0,为什么输出的结果中最大值为0呢?
应该怎样解决如上的问题呢?将程序修改如下:
练习2:计算一个整数数组的所有元素的和。
func main() {
var sum int
a := [...]int{10, 20, 55, 10, 30}
for i := 0; i < len(a); i++ {
sum += a[i]
}
fmt.Println(sum)
}
练习3:数组里面都是人的名字,分割成:例如:小王|小八|小蛋…”
func main() {
var a string
str := [...]string{"小王", "小八", "小蛋"}
for i := 0; i < len(str); i++ {
if str[i] != str[len(str)-1] {
a += str[i] + "|"
} else {
a += str[i]
}
}
fmt.Println(a)
}
# 结果
小王|小八|小蛋
或者
func main() {
var a string
str := [...]string{"小王", "小八", "小蛋"}
for i := 0; i < len(str)-1; i++ {
a += str[i] + "|"
}
fmt.Println(a + str[len(str)-1])
}
# 结果
小王|小八|小蛋
练习4:将一个整数数组的每一个元素进行如下的处理:如果元素是正数则将这个位置的元素的值加1,如果元素是负数则将这个位置的元素的值减1,如果元素是0,则不变。
func main() {
//将一个整数数组的每一个元素进行如下的处理:如果元素是正数则将这个位置的元素的值加1,如果元素是负数则将这个位置的元素的值减1,如果元素是0,则不变。
str := [...]int{10, 20, 0, -12, -13}
for _, k := range str {
switch {
case k < 0:
k -= 1
case k > 0:
k += 1
}
fmt.Println(k)
}
}
(1.5)数组冒泡排序
如何对数组中存储的数据,按照从大到小,或者从小到大进行排序?可以使用冒泡排序。
func main() {
arr := [...]int{12, 54, 10, 465, 30, -4, -210}
for i := 0; i < len(arr)-1; i++ {
for j := 0; j < len(arr)-1-i; j++ {
if arr[j] > arr[j+1] {
arr[j], arr[j+1] = arr[j+1], arr[j]
}
}
}
fmt.Println(arr)
}
(1.6)数组作为函数参数
数组也可以像变量一样,作为参数传递给函数,用法如下:
modify a=: [666 2 3 4 5]
main: a= [1 2 3 4 5]
注意:在main( )函数中,定义数组a, 然后调用modify( )方法传递数组,同时在modify( )方法中修改数组中第一个元素。最终输出结果发现,并不会影响main( )函数中数组a的值,这一点与其它编程语言是有区别的。
练习1:用方法来实现:有一个字符串数组: { “马龙”, “迈克尔乔丹”, “雷吉米勒”, “蒂姆邓肯”, “科比布莱恩特” },请输出最长的字符串。
思路:
1:在main( )函数中定义该数组,并且传递到GetLongest( )方法中
2:定义一个max变量用来存储最长的字符串,并且假设数组中的第一个元素是最长的。
3:通过循环,将数组中的元素取出来与max变量进行比较,如果长度比max变量中存储的长度要长,赋值给max
4:将结果返回
func main() {
//用方法来实现:有一个字符串数组: { "马龙", "迈克尔乔丹", "雷吉米勒", "蒂姆邓肯", "科比布莱恩特" },请输出最长的字符串。
arr := [...]string{"马龙", "迈克尔乔丹", "雷吉米勒", "蒂姆邓肯", "科比布莱恩特"}
max := arr[0]
for i := 0; i < len(arr); i++ {
if len(arr[i]) > len(max) {
max = arr[i]
}
}
fmt.Println(max)
}
或者
func lens(name [5]string) string {
max := name[0]
for i := 0; i < len(name); i++ {
if len(name[i]) > len(max) {
max = name[i]
}
}
return max
}
func main() {
//用方法来实现:有一个字符串数组: { "马龙", "迈克尔乔丹", "雷吉米勒", "蒂姆邓肯", "科比布莱恩特" },请输出最长的字符串。
str := [...]string{"马龙", "迈克尔乔丹", "雷吉米勒", "蒂姆邓肯", "科比布莱恩特"}
name := lens(str)
fmt.Println(name)
}
练习2:用方法来实现:请计算出一个整型数组的平均值。保留两位小数
思路:该题主要是通过循环的方式,将数组中的每个元素取出来进行累加,最后求平均数。注意输出格式
func getavg(math [5]int) float64 {
var sum int
for i := 0; i < len(math); i++ {
sum += math[i]
}
return float64(sum) / float64(len(math))
}
func main() {
//请计算出一个整型数组的平均值。保留两位小数
arr := [...]int{10, 30, 50, 64, 20}
math := getavg(arr)
fmt.Printf("平均值是:%.2f", math) //34.80
}
练习4:在上一题中,计算整型数组中的平均值,这个数组中的元素都是固定死的,如果将需求修改成数组中的3个元素是随机生成的,应该怎样进行处理?这就涉及到随机数的知识:随机数,可以理解成让计算机随机生成的一组数字。
在GO语言中,产生随机数的语法如下:
要产生随机数,还需要导入“math/rand”包,
rand.Seed(123),设置随机种子,由于随机种子是固定的,所以运行该程序,发现每次生成的随机数是一样的。
所谓的随机种子:随机数是由随机种子根据一定的计算方法计算出来的数值。所以,只要计算方法一定,随机种子一定,那么产生的随机数就不会变。
为了解决这个问题,可以让随机种子随时发生变化,所以可以利用时间来作为随机种子。 如果用时间来做随机种子,需要导入“time”包。
rand.Int( );每次产生的整型随机数都非常的大,所以可以限制范围,使用的是rand中的Intn( )方法。例如:rand.Intn(100),限制100内的随机数。
最终程序可以进行如下的修改:
最终,完整代码如下,该程序中涉及到了数组,函数嵌套调用,随机数等知识。通过该程序,体会出函数的一个很重要的优势,职责明确,RandomFunc( )函数是负责产生随机数,GetAvg( )负责对产生的数据进行计算。
练习4:用函数实现字符串数组{ “中国”, “美国”, “巴西”, “澳大利亚”, “加拿大” }中的内容反转,并在主函数(main( ))中,输出反转的结果
练习5:完成两个数组中元素的比较,判断其相同下标对应的元素是否完全一致。例如:a := [5]int{1, 2, 3, 4, 5}与b:= [3]int{1, 2, 3}进行比较,判断其数组元素是否完全一致。
思路:
1:可以先计算出数组a和数组b的长度,如果长度不一致,数组肯定不一致。
2:如果长度一致,可以通过循环将每个数组中元素取出来,进行比较。如果有一个元素不一致就退出循环。
那么上面举例的 a数组与b数组中的元素肯定不一致,因为长度不一致。
如果将数组b修改成b:=[5]int{1,2,3}, 是否一致呢?不一致,虽然长度相等,但是b[3]和b[4]都是0,元素不一致。
如果将数组b修改成b:=[5]int{5,1,2,3,4}是否一致呢?不一致,因为a[0]是1,而b[0]是5.
根据以上分析的思路,代码案例如下:在main( )函数中定义如下代码:
在上面的代码中,重点体会continue和break的用法。
虽然以上代码能够满足需求,但是问题是比较麻烦,GO语言中提供了另外一种方式进行比较,
直接使用“==”或”!=”进行比较。但是具体的要求是:
1:只支持 == 或 !=, 比较是不是每一个元素都一样
2:两个数组比较,数组类型要一样
除了可以进行比较以外,同类型的数组可以赋值
var d [5]int
d = a
fmt.Println(“d = “, d)
(1.7)二维数组(了解)
前面定义的数组只有一个下标,称之为一维数组,如果有两个下标,称之为二维数组。
关于二维数组,只要了解其基本使用就可以。
二维数组的定义如下:
b := [3][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}
可以理解数组b有3行4列构成,共能够存储12组数据。
//部分初始化,没有初始化的值为0
c := [3][4]int{{1, 2, 3}, {5, 6, 7, 8}, {9, 10}}
d := [3][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}}
e := [3][4]int{1: {5, 6, 7, 8}}//对第二列进行初始化,其它采用默认值。
由于二维数组是有行与列构成的,所以通过for循环进行初始化,需要循环嵌套,如下所示:
总结:有多少个[]就是多少维
有多少个[]就用多少个循环