【问题标题】:How to resolve this compilation error "Using unassigned local variable 'hak'" when using goto?使用 goto 时如何解决此编译错误“使用未分配的局部变量 'hak'”?
【发布时间】:2021-04-30 12:32:52
【问题描述】:

我正在尝试以下代码。它给了我一个警告“使用未分配的局部变量'hak'”。我想我在这里遗漏了一些东西。

我希望它在局部变量“hak”等于“0”时显示“3 defa yanlış giriş yaptınız. Müşteri hizmetleri temsilcisiyle görüşünüz. İyi günler dileriz.”。但它总是显示“Hatalı Giriş Yaptınız.Lütfen tekrar deneyiniz.2 hakkınız kalmıştır.

                   Console.Write("Seçmek istediğiniz 'Kullanıcı Adı'nı belirtiniz: ");
        string kullanici_adi = Console.ReadLine();
        FARKLISIFRE:
        Console.Write("Lütfen Şifrenizi giriniz: ");
        string sifre = Console.ReadLine();
        Console.Write("Girmiş olduğunuz şifreyi tekrar giriniz: ");
        string sifre2 = Console.ReadLine();

        int karsilastirma = String.Compare(sifre, sifre2);
        if (karsilastirma==0)
        {
            Console.WriteLine("Tebrikler! Kaydınız başarılı bir şekilde oluşturulmuştur.");
        }
        else
        {
            Console.WriteLine("Girmiş olduğunuz şifreler birbirinden farklıdır. Lütfen tekrar deneyiniz.");
            goto FARKLISIFRE;
        }

        Console.Write("Giriş yapmak için lütfen '1' seçeneğini giriniz: ");
        char komut = Convert.ToChar(Console.ReadLine());
        Console.Clear();
        if (komut=='1')
        {
            goto GIRIS;
        }

        else
        {
            Console.Write("Çıkış yaptınız. İyi günler dileriz.");
            goto END;
        }
        
        int hak = 3;

        GIRIS:
        Console.Write("Lütfen Kullanıcı Adınızı Giriniz: ");
        string kullanici_adi_giris = Console.ReadLine();
        Console.Write("Lütfen belirlemiş olduğunuz Şifrenizi giriniz: ");
        string sifre_giris = Console.ReadLine();

        int karsilastirma_k_adi = String.Compare(kullanici_adi, kullanici_adi_giris);
        int karsilastirma_sifre = String.Compare(sifre, sifre_giris);
        
        if (karsilastirma_k_adi == 0 && karsilastirma_sifre == 0)
        {
            Console.Write("Başarıyla Giriş Yaptınız. Hoşgeldiniz.");
        }
        else if (hak == 0)
        {
            Console.Write("3 defa yanlış giriş yaptınız. Müşteri hizmetleri temsilcisiyle görüşünüz. İyi günler dileriz.");
        }
        else
        {
            hak--;
            Console.WriteLine("Hatalı Giriş Yaptınız. Lütfen tekrar deneyiniz. {0} hakkınız kalmıştır.", hak);
            goto GIRIS;
        }
        
        END:
        Console.ReadKey();
    }

【问题讨论】:

  • CS0165 是错误代码。
  • 我认为问题不是从这里开始的。 hak 使用从这里开始的赋值进行初始化。我认为您有另一段代码导致此警告。
  • 我发布了完整的代码。
  • 我希望它显示“3 defa yanlış giriş yaptınız. Müşteri hizmetleri temsilcisiyle görüşünüz. İyi günler dileriz。”当局部变量“hak”等于“0”时。但它总是显示“Hatalı Giriş Yaptınız. Lütfen tekrar deneyiniz. 2 hakkınız kalmıştır.”
  • "else if (hak == 0)" 行导致错误代码。

标签: c# compilation variable-assignment goto unassigned-variable


【解决方案1】:

编译器看到将为变量hak 定义值的代码行标签 GIRIS 之前。不能保证该行会被执行,因为goto GIRIS这行代码可以到达GIRIS。

尝试改变这个:

int hak = 3;
GIRIS:

到这里:

GIRIS:
int hak = 3;

【讨论】:

  • 如果这对您有帮助,您能否将其标记为已接受的答案?谢谢。
  • 缺少您的解决方案。你可以看一眼@OlivierRogier 的解决方案。
  • 是的,哇。他写了很多代码来加快你的速度。
【解决方案2】:

您收到此编译错误,因为此行从未执行:

int hak = 3;

这是因为 GOTO、LABELS 的位置和这条线上方的测试条件if...else:你永远不会通过这条线。

要解决这个编译错误以及由此产生的设计问题,您需要重构所有这些以删除所有 GOTO。

确实,在编译时,在谈论执行之前,if ( komut == '1' ) ... else ...hak 的创建从未到达,转到GIRISEND

因此,当您尝试使用 hak 之后,它从未被分配过,编译器知道并告诉您。

为了编译,你需要写:

GIRIS:
int hak = 3;

但是使用 GOTO 是垃圾且不干净,非常糟糕的smell,并且是错误和怪异行为的根源。

每个世纪避免 goto 一次以上,请改用refactoring

GOTO still considered harmful?

Spaghetti code

使用局部方法的最小解决方案示例

if ( komut == '1' )
{
  int hak = 3;
  GIRIS(ref hak);
}
else
{
  Console.Write("Çıkış yaptınız. İyi günler dileriz.");
}

Console.ReadKey();

void GIRIS(ref int hak)
{
  Console.Write("Lütfen Kullanıcı Adınızı Giriniz: ");
  string kullanici_adi_giris = Console.ReadLine();
  Console.Write("Lütfen belirlemiş olduğunuz Şifrenizi giriniz: ");
  string sifre_giris = Console.ReadLine();

  int karsilastirma_k_adi = String.Compare(kullanici_adi, kullanici_adi_giris);
  int karsilastirma_sifre = String.Compare(sifre, sifre_giris);

  if ( karsilastirma_k_adi == 0 && karsilastirma_sifre == 0 )
  {
    Console.Write("Başarıyla Giriş Yaptınız. Hoşgeldiniz.");
  }
  else if ( hak == 0 )
  {
    Console.Write("3 defa yanlış giriş yaptınız. Müşteri hizmetleri temsilcisiyle görüşünüz. İyi günler dileriz.");
  }
  else
  {
    hak--;
    Console.WriteLine("Hatalı Giriş Yaptınız. Lütfen tekrar deneyiniz. {0} hakkınız kalmıştır.", hak);
    GIRIS(ref hak);
  }
}

【讨论】:

  • 非常感谢。
  • @SelçukÖzübek 我更新了答案,为方法的这一部分添加了一个简单但不是很高级也不是完全干净的重构。您应该对之前的 LABEL 和 GOTO 执行相同的操作。
  • 你真好。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-01
  • 2012-03-03
  • 2014-05-13
相关资源
最近更新 更多