【问题标题】:How to fix 'Use of unassigned local variable' in C# [duplicate]如何在 C# 中修复“使用未分配的局部变量”[重复]
【发布时间】:2019-08-04 04:47:59
【问题描述】:

我是 C# 新手,我的最后一门编程语言是 C

我不断收到未分配的局部变量“平均”的使用 与之相关的averageaverage /= 10;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int i, average;
            int[] scores = new int[10];

            Console.WriteLine("Enter 10 scores");
            for (i = 0; i < 10; i++)
            {
                scores[i] = Convert.ToInt32(Console.ReadLine());
            }

            for (i = 0; i < 10; i++)
            {
                average = scores[i] + scores[i + 1];
                i++;
            }

            average /= 10;

            Console.WriteLine("Average of All the Scores: {0}", average);
            Console.Read();
        }
    }
}

【问题讨论】:

  • 您可以通过将默认值设置为average 变量int average = 0; 来摆脱它

标签: c#


【解决方案1】:

当您声明变量“平均”时,将其设置为 0。

【讨论】:

  • 这样就消除了错误,但为什么编译器会在这种特定情况下将其标记出来?
  • @Caius:发生编译器错误是因为编译器没有执行任何静态流分析来确认average 变量已设置。根据 C# 的“明确赋值”规则,循环被忽略,因为循环甚至可能不迭代一次。因此,averagenot 明确分配的,因此是错误的。有关详细信息,请参阅标记的重复项,当然还有 C# 语言规范。
  • 因为它只在内部范围内分配了一个值,所以编译器不能确定它会达到。尽管在这种情况下它是相当明显的。所以从它的角度来看,它可能不得不使用平均值来划分,而没有它肯定有一个值集。
  • @peterduniho 感谢您提供的信息!了解循环位非常有帮助-我想我一定从未遇到过循环中的特定分配模式
  • @matt 我认为“内部范围”可能有点宽泛,因为您将if(true) average =0; 放在错误消失之前 - 这是我在这种情况下感到困惑的根源,因为我知道内部范围可以分配一个编译器会看到的值 - 不知道 Peter 提到的循环排除
【解决方案2】:

这是您的代码的固定版本,并与 cmets 说明了我做出更改的原因:

class Program
{
    static void Main(string[] args)
    {
        //fix the 'use of undefined' error
        int average = 0;
        int[] scores = new int[10];

        Console.WriteLine("Enter 10 scores");

        //it's better to scope loop iteration variables to the loop unless you specifically need them outside 
        for (int i = 0; i < 10; i++)
        {
            scores[i] = Convert.ToInt32(Console.ReadLine());
        }

        for (int i = 0; i < 10; i++)
        {
            //your old code would crash here, and had the wrong algorithm for calculating an average; it didn't sum all the entered values, just the last two 
            average += scores[i];
        }

        average /= 10;

        Console.WriteLine("Average of All the Scores: {0}", average);
        Console.Read();
    }
}

我很困惑为什么也会发生错误,因为第二个循环显然是在分配一个值,而且我知道内部范围可以设置值并且编译器会识别它们.. 对我来说也是学习日,因为我以前不知道即使设置了某些循环,它们也被排除在外,因此它们看起来肯定会运行。简单来说,似乎当设置循环以使其运行以变量为条件时,流分析认为在某些情况下循环可能不会运行,即使阅读代码的人清楚循环将始终跑步。考虑这些:

//this is fine, flow analysis determines this loop will always run
int average;
while(true){
  average = 0;
  break;
}
average /= 10;

//this raises the same error even though we as a human can definitely see this loop will always run
int average;
int w = 0;
while(w<1){
  average = 0;
}
average /= 10;

使循环以变量为条件意味着编译器可以确保变量已被分配

作为另一个更复杂的示例,您还可以使用这个奇怪的构造作为您的第一个循环来修复您的错误:

        for (int i = 0; true; i++)
        {
    average = 0;
            scores[i] = Convert.ToInt32(Console.ReadLine());
    if(i >= 10)
        break;
        }

编译器再次可以确保此循环将始终运行并且您的变量将被分配

这是彼得的评论,以防其他答案/评论消失:

编译器不执行任何静态流分析来确认平均变量已设置。根据 C# 的“确定赋值”规则,循环被忽略,因为循环甚至可能不迭代一次。因此,平均值不是绝对分配的,因此是错误的。有关详细信息,请参阅标记的重复项,当然还有 C# 语言规范。

【讨论】:

  • 讽刺的是,在您的第二个循环中,使用while(w&lt;1),您展示了编译器在代码流分析方面存在的另一个盲点。 IE。它没有注意到从不 exit 的循环,因此average 未明确分配(由 C# 规则)这一事实是无关紧要的,因为发生该错误的语句是不可访问的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-29
相关资源
最近更新 更多