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

时间:2015-09-01 14:31:59

标签: c# do-while

为什么我不允许使用我在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中的变量。

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

8 个答案:

答案 0 :(得分:17)

您的变量在do / while之外使用(在C#中,curlies通常定义范围),并且因为它在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#中,花括号{....}定义变量的范围。你不能在其范围之外使用变量,它不再是“可见的”,事实上,一旦它超出范围,它就可以被垃圾收集并且其内容可以是未定义的。

  

我知道这个,但为什么编译器不能这样做

你在评论中提到了这一点。答案不像看起来那么简单。它高度依赖于语言定义。某些语言(如Perl或更早的BASIC)允许在任何级别和任何范围内声明变量。其他语言允许变量的范围,并要求在使用变量之前声明变量(C#,Java,C ++,Python)。通常,但不一定,这对statically typed languages来说很常见,因为编译器需要事先知道要放入变量的数据类型,以便进行类型检查。 / p>

如果编译器强制声明而不是范围,则意味着所有变量都是全局变量,这在大型程序中很难,因为作为程序员,您必须维护使用变量名称的位置并保持唯一性。这非常繁琐(想想COBOL)。

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

编译器可以这样做,但C#的设计者已经决定明确的语言更好,并且在他们看来,声明变量 are a good thing ,因为它可以防止虚假错误和无法遵循的代码:

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

强制您声明变量并使其具有范围可以防止此类错误和相关类型的错误。

答案 1 :(得分:7)

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

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

答案 2 :(得分:2)

这个变量的范围就在循环内部......你不能在循环之外使用它

你应该这样做......

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

答案 3 :(得分:2)

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

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

答案 4 :(得分:2)

Per Specification do .. while的条件变量应该在循环之外声明,否则每次迭代都会重新初始化变量,这是没有意义的。

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

答案 5 :(得分:2)

更多一般规则:您无法范围之外使用C#中的变量 s {...},例如

  {
   int x = 123;
   ...
  }
  x = 456; // <- compile time error
代码中的

do {} while只意味着范围属于循环。

答案 6 :(得分:1)

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

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

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

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

答案 7 :(得分:0)

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