不能在 do/while 循环内声明的 while 子句中使用变量

Cannot use variable in while clause that is declared inside the do/while loop

为什么不允许我使用我在 do 中声明的变量并在 do/while 循环的 while 部分使用它?

do
{
   index += index;
   int composite = index + 1;
   // more code here
} while (UnsetBitmask(bitmasks, composite)); // cannot resolve symbol composite

我第一次看到这个我以为是编译器错误。所以我多次重新启动 Visual Studio 但它仍然无法识别 while.

中的变量

代码有什么问题,或者这是一个编译器错误?

这不是错误。 while 循环内的条件在定义变量的块之外。

int composite;
do
{
   index += index;
   composite = index + 1;
   // more code here
} while (UnsetBitmask(bitmasks, composite));

您的变量在 do/while 之外使用(在 C# 中,卷曲通常定义范围)并且由于它是在 do-while 内部声明的,因此您不能在该范围之外使用它。

您只需在循环外声明即可解决此问题。

int composite = 0;   // you are not required to set it to zero, as long 
                     // as you do not use it before you initialize it
do
{
   index += index;
   composite = index + 1;
   // more code here
} while (UnsetBitmask(bitmasks, composite)); 

注意(1),一次性声明和设置一个变量是很常见的做法,但这不是必须的,只要在使用前设置即可。

注(2):在C#中,大括号{....}定义了变量的作用域。你不能在它的范围之外使用一个变量,它不再是 "visible",事实上,一旦它超出范围,它就准备好被垃圾收集并且它的内容可以是不确定的。


i konw this,but why compiler cant do this

您在评论中提出了这个问题。答案并不像看起来那么微不足道。这在很大程度上取决于语言定义。某些语言,如 Perl 或更早的 BASIC,允许在任何级别和任何范围内声明变量。其他语言允许限定变量的范围并要求变量在使用前声明(C#、Java、C++、Python)。通常,但不一定,这对于 statically typed languages 很常见,因为 编译器需要事先知道您要将什么类型的数据放入变量中,以便进行类型检查 .

如果编译器会强制声明,而不是范围,这意味着所有变量都是全局的,这在较大的程序中很难,作为程序员,您将必须维护您使用的变量名称并维护独特性。这非常乏味(想想 COBOL)。

C# 添加了 dynamic 关键字,它允许具有动态 类型 的变量,但这仍然需要您在使用前定义变量。

编译器可以做到这一点,但是C#的设计者认为清晰的语言更好,在他们看来,声明变量are a good thing,因为它可以防止虚假错误和无法跟踪的代码:

// can you see the problem?
va1l = 1;
val1 = 2;
vall = va1l + vall;

强制您声明变量并限定它们的作用域可防止此类错误和相关类型的错误。

这个变量的作用域就在循环内....你不能在循环外使用它

你应该这样做....

int composite;
do
{
   index += index;
   composite = index + 1;
   // more code here
} while (UnsetBitmask(bitmasks, composite)); 

虽然 { ... } 表示一个代码块,但该块中的所有变量都限于该特殊范围。您的条件超出此范围,因此无法访问那里的变量。在循环外声明它并且它有效:

int composite = 0;
do
{
    index += index;
    composite += index + 1;
    // more code here
} while (UnsetBitmask(bitmasks, composite));

根据 Specificationdo .. while 的条件变量应该在循环外声明,否则在每次迭代中变量将被重新初始化,这是没有意义的。

        int composite;
        do
        {
            index += index;
            composite = index + 1;
            // more code here
        } while (UnsetBitmask(bitmasks, composite)); 

更多一般规则:您不能在其范围之外使用变量C# 是 {...},例如

  {
   int x = 123;
   ...
  }
  x = 456; // <- compile time error

do {} while 在你的代码中只是意味着范围属于循环。

    int composite;
do
{
   index += index;
   composite = index + 1;
   // more code here
} while (UnsetBitmask(bitmasks, composite));

我知道“while” 块之外,但考虑一下:

for (int i = 0; i < 10; i++) 
{
  Console.WriteLine(i);
}

在这里,变量“i”是块范围的(在 for 块之外不可见),实际上在每次循环迭代时都会创建一个新的“实例”。但实际定义在块之外。

你可以说“for”声明属于块,但我会说“while”也属于块。只是不一致!