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

M.k*_*ary 6 c# do-while

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

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

我第一次看到这个,我认为这是一个编译器错误.所以我多次重启Visual Studio但仍然无法识别变量while.

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

Abe*_*bel 16

您的变量在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)); 
Run Code Online (Sandbox Code Playgroud)

注意(1),通常的做法是一次性声明和设置变量,但这不是必需的,只要在使用之前进行设置即可.

注意(2):在C#中,花括号{....}定义变量的范围.你不能在其范围之外使用变量,它不再是"可见的",实际上,一旦它超出范围,它就可以被垃圾收集并且其内容可以是未定义的.


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

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

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

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

编译器可以做到这一点,但C#的设计者已经决定清晰的语言更好,并且在他们看来,声明的变量是一件好事,因为它可以防止虚假错误和不可能遵循的代码:

// can you see the problem?
va1l = 1;
val1 = 2;
vall = va1l + vall;
Run Code Online (Sandbox Code Playgroud)

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


Sam*_*Sam 7

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

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