Golang-无效的数组边界

huangapple go评论69阅读模式
英文:

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 &quot;fmt&quot;
 
func main(){
   var subj float64
   fmt.Println(&quot;Enter how much you have subjects inn school: &quot;)
   fmt.Scanf(&quot;%f&quot;, &amp;subj)
   s := subj
   var mark 
展开收缩
float64 var a float64 for a = 0; a&lt;s; a++{ fmt.Scanf(&quot;%f&quot;, &amp;mark) } var total float64 var i float64 for i= 0; i&lt;subj; i++{ total += mark[i] } fmt.Println(total/subj) }

What is the problem?

答案1

得分: 7

规范:数组类型:

长度是数组类型的一部分;它必须评估为一个非负的常量,可以由int类型的值表示。

你的长度在

展开收缩
float64中不是一个常量。

使用切片类型而不是数组类型,并且要知道你必须使用整数类型作为长度,例如:

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))
英文:

Spec: Array types:

> 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

展开收缩
float64 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 &lt; len(mark); i++ {
    fmt.Scanf(&quot;%f&quot;, &amp;mark[i])
}

Or you can even use for ... range to range over the indices of the slice:

for i := range mark {
    fmt.Scanf(&quot;%f&quot;, &amp;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(&quot;Number of subjects:&quot;)
fmt.Scanln(&amp;n)
for i := 0; i &lt; n; i++ {
	fmt.Scanln(&amp;mark)
	total += mark
}
fmt.Println(&quot;Average:&quot;, 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(&quot;Number of subjects: &quot;)
if _, err := fmt.Scanln(&amp;n); err != nil || n &lt;= 0 {
	fmt.Println(&quot;Wrong number!&quot;)
	return
}
for i := 0; i &lt; n; i++ {
	fmt.Printf(&quot;Enter %d. mark: &quot;, i+1)
	if _, err := fmt.Scanln(&amp;mark); err != nil || mark &lt; 1 || mark &gt; 5 {
		fmt.Println(&quot;Wrong mark, enter it again!&quot;)
		fmt.Scanln()
		i-- // We&#39;re gonna re-scan the same mark
	} else {
		total += mark
	}
}
fmt.Println(&quot;Average:&quot;, float64(total)/float64(n))

huangapple
  • 本文由 发表于 2016年1月27日 15:49:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/35031502.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定