for循环中计数器变量的范围是啥?

Posted

技术标签:

【中文标题】for循环中计数器变量的范围是啥?【英文标题】:What is the scope of the counter variable in a for loop?for循环中计数器变量的范围是什么? 【发布时间】:2011-03-26 12:03:16 【问题描述】:

我在 Visual Studio 2008 中收到以下错误:

Error 1 A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else

这是我的代码:

for (int i = 0; i < 3; i++)

  string str = "";


int i = 0; // scope error
string str = ""; // no scope error

我知道一旦循环终止,str 将不复存在,但我也认为i 的范围也仅限于for 循环。

所以i 与在for 循环之外声明的变量具有相同的范围?

编辑:

为了清楚起见,我使用的是 C#。我正在讨论删除“C”标签。但是,由于正确答案解释了两者之间的区别,我认为留下两个标签是有意义的。

我在上面的代码注释中有一个错误:

for (int i = 0; i < 3; i++)

  string str = "";


int i = 0; // scope error
string str = ""; // also scope error,
                 // because it's equivalent to declaring
                 // string str =""; before the for loop (see below)

【问题讨论】:

你已经标记了这个 c# 和 c。你问的是哪种语言?答案可能会有所不同,具体取决于您所指的语言。 请参阅***.com/questions/2693138/… 了解相同的问题,Eric Lippert 给出了很好的回答。另见***.com/questions/1196941/… 和***.com/questions/2059210/… 为了清楚起见,标记c#c(或c++)没有问题,如果您开始使用 我在 C# 3.0 中收到以下错误(Visual Studio 2008)... 和更高版本 for-loop 范围的 C# 规则与 ANSI C 有何不同?,这似乎是您的本意。但是您没有在原始问题中的任何地方指定您使用的是什么语言,在这种情况下,大多数人都会查看标签......这就是两个语言标签的问题所在。 【参考方案1】:

我认为你们都混淆了 C++ 和 C#。

在 C++ 中,过去在 for 表达式中声明的变量的范围在其后面的块之外。这在前段时间被改变了,因此在 for 表达式中声明的变量的范围在它后面的块的内部。 C# 遵循后一种方法。但两者都与此无关。

这里发生的情况是,C# 不允许一个作用域在外部作用域中隐藏同名的变量。

因此,在 C++ 中,这曾经是非法的。现在是合法的。

for (int i; ; )


for (int i; ; )


同样的事情在 C# 中也是合法的。共有三个作用域,未定义“i”的外部作用域和两个子作用域,每个作用域都声明了自己的“i”。

但你正在做的是:

int i;
for (int i; ; )


这里有两个作用域。一个外部声明一个“i”,一个内部声明一个“i”。这在 C++ 中是合法的 - 外部的 'i' 是隐藏的 - 但在 C# 中是非法的,无论内部范围是 for 循环、while 循环还是其他。

试试这个:

int i;
while (true)

    int i;

同样的问题。 C# 不允许在嵌套范围内具有相同名称的变量。

【讨论】:

这个是正确答案。 C# 不允许您隐藏变量,因为它可能会造成混淆。 C++ 不在乎。它与for 循环语法,或者变量是在函数的顶部还是底部声明,或其他任何东西无关... 我发现实际阅读错误信息有时会有所帮助。【参考方案2】:

for循环后增量器不存在。

for (int i = 0; i < 10; i++)  
int b = i; // this complains i doesn't exist
int i = 0; // this complains i would change a child scope version because the for's  is a child scope of current scope

你不能在 for 循环之后重新声明 i 的原因是因为在 IL 中它实际上会在 for 循环之前声明它,因为声明发生在范围的顶部。

【讨论】:

+1 Hoffa:我猜你已经猜到了,但你为什么要删除你的示例代码?这是一个很好的观点。 @JohnB:我错误地声明了错误,现在已修复。有时只需要考虑这些事情:) @JohnB:请说明您使用的是什么语言。 @Luca Matteis:C#,但我认为这无关紧要! Hoffa 还指出变量声明的顺序是可逆的,这是一个好点,但 Jeff Dege 给出了真正的答案。【参考方案3】:

是的。语法上:新的作用域在花括号定义的块内。功能上:在某些情况下,您可能需要检查循环变量的最终值(例如,如果您中断了)。

【讨论】:

+1 对,在 内,这完全有道理,并且保持一致!【参考方案4】:

只是一些背景信息:序列没有涉及。只有范围的概念——方法范围和for 循环的范围。因此,“一旦循环终止”是不准确的。

因此,您发布的内容与此相同:

int i = 0; // scope error
string str = ""; // no scope error

for (int i = 0; i < 3; i++)

  string str = "";

我发现这样思考会让答案更“适合”我的心智模型。

【讨论】:

+1 谢谢,很好!这样就更清楚了! (但没有直接回答我的问题,所以你没有得到支票) str 的双重声明在 C++ 中很好,但在 C# 中是范围错误。 OP 问题中的问题不在于在 same 范围内声明两个变量,而是 C# 不允许您在 nested 范围内拥有相同的变量,因为它可以令人困惑。 C++ 让你做令人困惑的事情。 约翰,当然,但你说什么让我的回答不恰当或没有帮助(假设你投票给我)?正如我所说,这是一些背景信息,正如 OP 所说,'谢谢,很好!这样就更清楚了”。 两个str 变量do 导致C# 中的错误,就像两个i 变量一样。两者都不会导致 C++ 中的错误。您的代码 sn-p 在任何一种语言中都是错误的。我并不是要继续说下去,但我认为您的回答增加了 OP 的困惑,而不是清除它。 @John Kugelman:最初说string str = ""; // no scope error 是我的错。但是,Kieren 确实明确了为什么我首先得到错误(这是因为该序列对于编译器是可逆的)。但是,我将支票交给 Jeff Dege,因为他提供了更明确的答案。

以上是关于for循环中计数器变量的范围是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在for循环声明中初始化变量的范围实际上不仅仅是块范围吗?

C++基于范围的for循环详解

js中的4种循环结构

为啥在嵌套函数之外声明一个计数器变量会使循环慢 5 倍?

C#的for循环使用方法

经过for循环后计数器变量未更改