Scope of a 'for' loop at declaration of a variable
我在编码时遇到了这种奇怪的行为。所以我在这里问。
声明变量时,for循环的作用域是什么?
这段代码编译得很好
1 2 3
| for (int i = 0; i < 10; i++) { }
for (int i = 0; i < 10; i++) { } |
这意味着两个int i不在同一范围内。
但这段代码不能编译。
1 2 3
| for (int i = 0; i < 10; i++) { }
int i; // Conflicts with both first loop and second one.
for (int i = 0; i < 10; i++) { } |
这意味着循环中间的int i具有与第一个循环和第二个循环相同的范围。
但是在两个EDCOX1,0个循环中,EDOCX1?1的范围如何不同,但与EDCOX1中间的范围相同?1?因为我现在看到他们在同一水平。
我知道第二个代码不能编译。如果范围中存在问题,那么为什么要编译第一个代码呢?这是编译器内部的异常吗?
- 它不是在相同的范围内,而是嵌套的,这也是被禁止的。请看这个问题来回答类似的问题:StAdvOpj.com/问题/ 6156449/& Helip;
- 有趣的是,EDOCX1(注:内部EDOCX1(注:1))确实存在竞争。
- @dmitrybychenko:这是因为我只存在于由大括号定义的块中(在for循环之间)。
- 外部i是在第一个for循环之前还是之后,这并不重要。编译器不需要它。点。如果将声明从下到上移动,编译器错误可以防止粗心的错误。这很容易避免。
- 因为没有答案表明:假设This means the int i in middle of loops has the same scope of first loop and the second loop.是错误的,这是这里的主要问题。
- 这个问题是如何在堆栈溢出启动7年后不重复的?
编译器不检查在另一个变量之前或之后申报的变量。所有的事情都是这个范围。如果你使用i,在环形圈内,就没有办法区分哪些i你喜欢使用。就第一个环节而言,一个错误仍然存在,因为i块被宣布为封装,第一个环节也被宣布为封装。
例如,后续行动将不编纂,即使是j也不可见,因此,在i方面不应有任何模棱两可之处:
1 2 3 4 5 6 7 8 9
| {
{
int i = 1;
int j = 1;
}
int i = 0; // compiler error: A local variable i cannot be declared in this scope (...)
// j is not visible here
} |
Edit regarding the comment:
为什么跟踪得很好?
ZZU1
当你宣布一个for时,只有在环形块内才可见。这意味着两个变量的范围被切断,因为没有一条代码线,在哪儿一块"超越"另一块。
- 对。当然,它与第二个循环冲突,但是这个循环也不编译。for (int i = 0; i < 10; i++) { }int i;。但是,怎样才能实现for (int i = 0; i < 10; i++) { }for (int i = 0; i < 10; i++) { }?
- @正如大多数答案所解释的,变量的范围不是从它的声明开始的,而是整个块。for循环定义一个块
- 谢谢你的回答。所以它和{int i; } { int i; }一样是可能的。
- @是的,你可以这样看。
- 等等,这难道不只是意味着局部变量不能隐藏外部变量,加上声明范围是整个块,而不仅仅是它被写入和转发的点吗?简单地说,for (int i; ...) int i;和int i; for (int i; ..)是一样的,这一切就更清楚了。
一个圈的范围,EDOCX1&15
1 2 3 4 5 6 7
| {
INIT;
while (COND) {
BLOCK;
INCR;
}
} |
这是一个圆圈,可以是两个圆圈的最佳想法。(注:从for到while的上次转换不会预见到continue的行为。)然而,这一问题并不是围绕着这个问题。
在C+中,如果你以同样的名称声明了一个范围变量,如外观中的某个东西,你"暗影"它,静默地掩盖它直到它结束。当他们发展到C 35;,他们觉得这太反直觉了,而且错误的代词。在C 35中,它是一个语法错误的阴影变量,从一个外观。通过引进int i到外面的范围,现在对for来说,这是非法的。
- 很好地提到了替代范围。我想把这个细节包括在我的答案中,但我不记得for是如何精确地翻译的。
在环路中声明的变量只在环形块内,但当你声明环形块外的变量时,环形件内的变量就没有相同的名称,因为它混淆了你在环形体中所指的变量。
我会以你的代码为例
1 2 3 4 5
| int i =0;
for (int i = 0; i < 10; i++)
{
i = i+1; // now compiler is confused which i you mean here, so i complains on compile time that you have two with same name
} |
因此,如果你已经声明了在你所做的loops之间,可变i的范围,那么两者都是可以获得的,那么,如果你重新开始第一个loop,它将仍然是投诉,因为变量的全球性范围在LOOP之外:
1 2 3 4 5
| for (int i = 0; i < 10; i++)
{
i = i+1; // now compiler is still confused which i you mean
}
int i =0; |
- 事实并非如此,你错了。OP称它与第一环中i的声明冲突。你应该尝试编译OP的代码。
- EDCOX1 10为什么编译器混淆??
- 因为我们有两个变量,第二个变量是全局变量,所以它的作用域也在for循环中
- 但为什么这个全局变量与第一个循环的内部变量冲突?甚至这个全局i也是在第一个循环的作用域之后声明的。
- 它是全局的,无论它是在循环之前还是之后写入,点是在循环外部变量对两个循环都有全局作用域
- @沙哈拉尔只要"i"在同一范围内,它在哪里被宣布就无关紧要。它可能在之前或之后,C不会自上而下编译。
- @瑞恩塞尔是的!你说得对,但如果不是自上而下,它是如何工作的呢?
- @Shaharyar我认为它更多的是在外部编译,我的意思是它先编译外部作用域,然后编译内部作用域。我建议做进一步的研究,因为我的知识是有限的。
- @Ryansearle感谢您将其添加到我的知识中。)
- @Shaharyar代码编译到IL,编译时检查代码是否有错误,以便在它所抱怨的范围内找到两个同名变量,正如Ryansearle所说,这里的顺序无关紧要。
- @ehsansajjad我知道它是如何编译代码的,但我不知道顺序无关紧要。
- 这不是全局范围…
- @Rubbrduck我的意思是它现在在两个循环中都有作用域,因为它对两个循环都是全局的
- global是一个非常糟糕的单词选择@ehsansajjad。全局范围变量是一个实际的东西,它们不是全局范围的。这些都是私有范围的方法,该方法包含循环的范围。
- @我承认我用错词了,谢谢你的反馈
我不认为你把int i;放在什么地方。
编译器第一次扫描现场,然后开始扫描表达式。由于i已被确认为一个领域,因此不需要汇编。
没有什么不对劲的。在第二个例子中,你确定了一个外在的i,然后试图在每一个环节中重新定义它。
在一个for中宣布的变量是局部的,但你已经在外视野中确定了另一个变量。
我想你已经问过另一个问题,假设一个变量起始点的范围是从宣言点?
一个变量范围是确定的区块,不受其位置的影响。当编译器在宣言之前拒绝使用变量时,它仍然在范围内。
- 实际上,op的代码与第一个for循环冲突,您没有解释任何有关它的内容。
- @实际上,我写过,关于内环和外环,不是第一个或第二个。外部与两个循环冲突。评论他们中的任何一个,你会发现你仍然有冲突。这就是为什么我没有指定一个或另一个循环
- 在某种程度上,变量只有在声明之后才"在范围内"。你不能在申报之前使用i。这种行为可能是编译器团队最简单的实现。编译器很难,所以我不怪他们。
您可以在环路之外声明当前的功能。Either Declare only Outer int i,and remove int ifrom both loops,or just remove this out variable.