英文:
Golang- invalid array bound
问题
当我运行下面的代码时,我得到了错误信息:
school_mark.go:8: invalid array bound s
我的代码:
package main
import "fmt"
func main(){
var subj float64
fmt.Println("输入你在学校有多少门科目:")
fmt.Scanf("%f", &subj)
s := subj
var mark 展开收缩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)
}
问题是什么?
英文:
When I run the code below I get the error:
school_mark.go:8: invalid array bound s
My code:
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 展开收缩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)
}
What is the problem?
答案1
得分: 7
长度是数组类型的一部分;它必须评估为一个非负的常量,可以由
int
类型的值表示。
你的长度在
中不是一个常量。
使用切片类型而不是数组类型,并且要知道你必须使用整数类型作为长度,例如:
var mark []float64 = make([]float64, int(s))
或者简写为:
mark := make([]float64, int(s))
在以后的代码中,始终使用整数类型(例如int
)作为索引。你可以在for
循环中声明它,例如:
for i := 0; i < len(mark); i++ {
fmt.Scanf("%f", &mark[i])
}
或者你甚至可以使用for ... range
来遍历切片的索引:
for i := range mark {
fmt.Scanf("%f", &mark[i])
}
我还建议在所有地方使用int
类型:如果非整数的科目数量和分数本身没有意义。
另外,fmt.Scanf()
不会消耗换行符,后续的fmt.Scanf()
调用将立即返回错误。
你还应该检查错误或成功解析的值,这两者都是由fmt.Scan*()
函数返回的。
此外,你不必两次循环切片,你可以在第一次循环中计算总和。
更进一步,你甚至不必将分数存储在切片中,你可以只询问输入的分数数量,即时计算总和并打印平均值。
类似这样:
var n, total, mark int
fmt.Println("科目数量:")
fmt.Scanln(&n)
for i := 0; i < n; i++ {
fmt.Scanln(&mark)
total += mark
}
fmt.Println("平均值:", float64(total)/float64(n))
如果你要添加所有必需的检查,代码可能如下所示:
var n, total, mark int
fmt.Print("科目数量:")
if _, err := fmt.Scanln(&n); err != nil || n <= 0 {
fmt.Println("错误的数量!")
return
}
for i := 0; i < n; i++ {
fmt.Printf("输入第 %d 个分数:", i+1)
if _, err := fmt.Scanln(&mark); err != nil || mark < 1 || mark > 5 {
fmt.Println("错误的分数,请重新输入!")
fmt.Scanln()
i-- // 我们将重新扫描相同的分数
} else {
total += mark
}
}
fmt.Println("平均值:", float64(total)/float64(n))
英文:
> The length is part of the array's type; it must evaluate to a non-negative constant representable by a value of type int
.
Your length in
is not a constant.
Use a slice instead of an array type, and know that you have to use integer type for the length, e.g.:
var mark []float64 = make([]float64, int(s))
Or short:
mark := make([]float64, int(s))
Going forward, always use integer types (e.g. int
) for indices. You can declare it in for
like:
for i := 0; i < len(mark); i++ {
fmt.Scanf("%f", &mark[i])
}
Or you can even use for ... range
to range over the indices of the slice:
for i := range mark {
fmt.Scanf("%f", &mark[i])
}
I would also use int
type everywhere: the number of subjects and marks themselves do not have a meaning if they are non integers.
Also fmt.Scanf()
does not consume newline, subsequent fmt.Scanf()
call will return immediately with an error.
You should also check errors or successfully parsed values, both which are returned by the fmt.Scan*()
functions.
Also you don't have to loop the slice twice, you can calculate total (the sum) in the first.
Going even more forward, you don't even have to store the marks in the slice, you could just ask the entered number of marks, calculate sum on the fly and print the average.
Something like this:
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))
If you were to add all the required checks, it could look like this:
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))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论