当我运行下面的代码时,出现错误:
school_mark.go:8: invalid array bound s
Run Code Online (Sandbox Code Playgroud)
我的代码:
package main
import "fmt"
func main(){
var subj float64
fmt.Println("Enter how much you have subjects inn school: ")
fmt.Scanf("%f", &subj)
s := subj
var mark [s]float64
var a float64
for a = 0; a<s; a++{
fmt.Scanf("%f", &mark)
}
var total float64
var i float64
for i= 0; i<subj; i++{
total += mark[i]
}
fmt.Println(total/subj)
}
Run Code Online (Sandbox Code Playgroud)
问题是什么?
长度是数组类型的一部分;它必须计算为由 类型的值表示的非负常量
int。
你的长度[s]float64不是一个常数。
使用切片而不是数组类型,并且知道必须使用整数类型作为长度,例如:
var mark []float64 = make([]float64, int(s))
Run Code Online (Sandbox Code Playgroud)
或者短:
mark := make([]float64, int(s))
Run Code Online (Sandbox Code Playgroud)
展望未来,始终使用整数类型(例如int)作为索引。你可以这样声明它for:
for i := 0; i < len(mark); i++ {
fmt.Scanf("%f", &mark[i])
}
Run Code Online (Sandbox Code Playgroud)
或者您甚至可以使用for ... range范围来覆盖切片的索引:
for i := range mark {
fmt.Scanf("%f", &mark[i])
}
Run Code Online (Sandbox Code Playgroud)
我还会int在任何地方使用类型:如果主题和标记的数量不是整数,那么它们本身就没有意义。
也fmt.Scanf()不会消耗换行符,后续fmt.Scanf()调用将立即返回并出现错误。
您还应该检查错误或成功解析的值,这两者都是由fmt.Scan*()函数返回的。
另外,您不必循环切片两次,您可以在第一次中计算总计(总和)。
更进一步,您甚至不必将标记存储在切片中,您只需询问输入的标记数量,即时计算总和并打印平均值。
像这样的东西:
var n, total, mark int
fmt.Println("Number of subjects:")
fmt.Scanln(&n)
for i := 0; i < n; i++ {
fmt.Scanln(&mark)
total += mark
}
fmt.Println("Average:", float64(total)/float64(n))
Run Code Online (Sandbox Code Playgroud)
如果您要添加所有必需的检查,它可能如下所示:
var n, total, mark int
fmt.Print("Number of subjects: ")
if _, err := fmt.Scanln(&n); err != nil || n <= 0 {
fmt.Println("Wrong number!")
return
}
for i := 0; i < n; i++ {
fmt.Printf("Enter %d. mark: ", i+1)
if _, err := fmt.Scanln(&mark); err != nil || mark < 1 || mark > 5 {
fmt.Println("Wrong mark, enter it again!")
fmt.Scanln()
i-- // We're gonna re-scan the same mark
} else {
total += mark
}
}
fmt.Println("Average:", float64(total)/float64(n))
Run Code Online (Sandbox Code Playgroud)